🐻‍❄️

[Jetpack Compose]BoxのmatchParentで特定の要素に他の要素をマスクする

2023/04/28に公開

方法

特定の要素の上に他の要素をマスクしたい場合にはBox内に配置した子要素に対してmatchParentを付加することでうまく実装ができる。

  • BoxにはwrapContentSizeを付加して子要素の一番大きいサイズにあわせる
  • 子要素のTextsizeを付加して固定サイズにする
  • 子要素のSpacermatchParentSizeを付加してBoxのサイズにあわせる(Spacerの子要素を除く,子要素の中で一番大きいサイズにあわせる、ようにする)
  • このように実装するとBoxTextのサイズにあわせる、SpacerBoxのサイズにあわせる、という関係性が構築できる。そのためSpacerTextのサイズが同じになり、このようなマスク表示が可能になる
@Composable
fun SampleBox() {
    Box(
        modifier = Modifier
            .wrapContentSize()
            .background(Color.White)
    ) {
        Text(
            text = "TEXT",
            modifier = Modifier
                .size(200.dp)
                .background(Color.Red.copy(alpha = 0.5f))
        )

        Spacer(
            modifier = Modifier
                .matchParentSize()
                .background(Color.Green.copy(alpha = 0.5f))
        )
    }
}

よくある間違い

特定の要素の上に他の要素をマスクしたい場合によくある間違いはBox内に配置した要素に対してfillMaxSizeを付加してしまう間違い。

  • BoxにはwrapContentSizeを付加して子要素の一番大きいサイズにあわせる
  • 子要素のTextsizeを付加して固定サイズにする
  • 子の要素のSpacerfillMaxSizeを更かして可能な限り大きなサイズにする
  • このように実装するとBoxSpacerのサイズにあわせる、Spacerは可能な限りサイズを大きくする、という関係性が構築される。そのため以下のようにSpacerのサイズが大きくなってしまい、Textのサイズが同じにならずマスク表示にはならない。
@Composable
fun SampleBox() {
    Box(
        modifier = Modifier
            .wrapContentSize()
            .background(Color.White)
    ) {
        Text(
            text = "TEXT",
            modifier = Modifier
                .align(Alignment.Center)
                .size(200.dp)
                .background(Color.Red.copy(alpha = 0.5f))
        )

        Spacer(
            modifier = Modifier
                .fillMaxSize()
                .background(Color.Green.copy(alpha = 0.5f))
        )
    }
}

参考資料

https://developer.android.com/jetpack/compose/modifiers?hl=ja#matchparentsize-box

Discussion