7
0

More than 1 year has passed since last update.

Jetpack Compose で背景画像を repeat させる

Last updated at Posted at 2022-03-07

Android で背景画像を repeat させるには、以下のように実装します。1

tile_background.xml
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:antialias="true"
    android:dither="false"
    android:filter="false"
    android:gravity="fill"
    android:src="@android:drawable/alert_dark_frame"
    android:tileMode="repeat" />
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/tile_background" />

ビルド結果は以下のようになります。

ですが、これを Jetpack Compose でやるとなった場合、残念ながら対応する Composable は用意されていません(2022 年 3 月 4 日時点)。

解決策

以下のように AndroidView を用意して、その中で背景画像を repeat させるようにします。

TiledImage.kt
@Composable
fun TiledImage(
    modifier: Modifier = Modifier,
    @DrawableRes id: Int,
    contentDescription: String? = null
) {
    AndroidView(
        modifier = modifier
            .semantics {
                contentDescription?.let {
                    this.contentDescription = it
                }
            },
        factory = {
            val bitmapDrawable = BitmapDrawable(it.resources, BitmapFactory.decodeResource(it.resources, id)).apply {
                tileModeX = Shader.TileMode.REPEAT
                tileModeY = Shader.TileMode.REPEAT
            }
            View(it).apply {
                background = bitmapDrawable
            }
        }
    )
}

@Preview(showBackground = true)
@Composable
private fun Preview() {
    TiledImage(id = R.drawable.alert_dark_frame)
}

ポイントとしては、BitmapDrawable を生成し、tileModeX および tileModeYShader.TileMode.REPEAT を設定することです。

factory = {
    val bitmapDrawable = BitmapDrawable(it.resources, BitmapFactory.decodeResource(it.resources, id)).apply {
        tileModeX = Shader.TileMode.REPEAT
        tileModeY = Shader.TileMode.REPEAT
    }
    View(it).apply {
        background = bitmapDrawable
    }
}

こちらは任意ですが、contentDescription を設定してテストしやすいように実装するのがおすすめです。

// contentDescriptionを設定してテストしやすいように
modifier = modifier
    .semantics {
        contentDescription?.let {
            this.contentDescription = it
        }
    }

プレビュー結果は以下のようになります。

もっとより良い方法がありましたらご指摘ください。

  1. Y.A.M の 雑記帳: Android 背景画像を repeat させる より引用。

7
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0