Android / Kotlin / Programming

Jetpack Composeで背景をrepeat表示 (Android View不使用)

やりたいこと

Jetpack Composeを使って、このベクター画像を

下のようにリピートして敷き詰めたい

準備

これから使うDrawable.toBitmapはandroidx.core:core-ktxのバージョンが1.1.0以上でないと使用できません。
2023/10/14現在の最新の安定版は1.9.0なのでこれを指定します。
appのgradleに下記を追加してください。

dependencies {
    implementation("androidx.core:core-ktx:1.9.0")
}

解決策

fun vectorToImageBitmap(
    context: Context,
    @DrawableRes id: Int
): ImageBitmap? {
    val drawable = ContextCompat.getDrawable(context, id) ?: return null
    return drawable.toBitmap().asImageBitmap()
}

これが変換関数です。
ContextCompat.getDrawable(context, id)で指定したリソースのDrawableを取得します。
あとはdrawableからtoBitmapでBitmapに変換し、asImageBitmapでImageBitmapを取得しています。

使用例

@Composable
private fun NotebookScreen() {
    val context = LocalContext.current
    val image = vectorToImageBitmap(
        context = context,
        id = R.drawable.path_to_vector
    )
    val brush = remember(key1 = image) {
        ShaderBrush(
            shader = ImageShader(
                image = image!!,
                tileModeX = TileMode.Repeated,
                tileModeY = TileMode.Repeated,
            )
        )
    }
    
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(brush = brush)
    ) {
        Text(text = "hi", color = Color.Blue)
    }
}

fun vectorToImageBitmap(
    context: Context,
    @DrawableRes id: Int
): ImageBitmap? {
    val drawable = ContextCompat.getDrawable(context, id) ?: return null
    return drawable.toBitmap().asImageBitmap()
}

終わり


関連エラー

色々試す中で
「android.graphics.drawable.VectorDrawable cannot be cast to android.graphics.drawable.BitmapDrawable」
とエラーが表示されました。同じエラーに出会った方は解決策を見ていただければと思います。

余談

ベクター画像を下のようにModifierのbackgroundに指定して、リピート表示させようとしていました。

val brush = remember(vectorImage) {
    ShaderBrush(
        shader = ImageShader(
            image = vectorImage, // image引数の型はImageBitmap
            tileModeX = TileMode.Repeated,
            tileModeY = TileMode.Repeated,
        )
    )
}

Modifier
    .fillMaxSize()
    .background(brush = brush)

ImageShaderの引数「image」はImageBitmapが指定されています。

背景にベクター画像を設定したことはなかったのですが、「painterResource(resouce_id)で取得できるクラスがImageBitmapを継承してるか、変換関数を持ってるでしょ!」と思ってやってみました。
案の定、そんなものはなく、自分で関数を作る次第になりました笑。

painterResource関数で取得できるのはVectorPainterで継承しているのはPainterのみです。最終目標のImageBitmapはどうしてもこのクラスからは取得できなかったです。
もし他の方法やより簡単なものがあればコメントください!

一覧

クラス・抽象クラス・インターフェース(A-z順)
ImageBitmap
Painter
ShaderBrush
VectorPainter

関数(A-z順)
asImageBitmap
background
ImageShader
painterResource
toBitmap

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です