Jetpack Composeでコンポーネントを丸く切り抜きたい

この記事をシェア
JetpackCompose一問一答

Modifierを使って、画像などのコンポーネントを丸く切り抜く方法を紹介します。背景色を設定しつつ切り抜きも行う方法も紹介します。

やりたいこと

画像を丸く切り抜く
背景色の設定と切り抜きを合わせて行う

左の例は、画像を単純に丸く切り抜いて表示しています。

右の例は、透過画像の背景に緑色を指定しつつ、丸く切り抜いて表示しています。

環境

以下の環境で確認しています。

  • Kotlin 1.6.10
  • Jetpack Compose 1.1.1

単純な切り抜き

Box(
    contentAlignment = Alignment.Center,
    modifier = Modifier
        .background(Color.Black)
        .size(100.dp),
) {
    Image(
        painter = painterResource(R.drawable.hitsuji),
        contentDescription = null,
        modifier = Modifier
            .size(64.dp)
            .clip(CircleShape)
    )
}

単純に切り抜きたい場合は、Modifier.clip()を使います。引数のshapeにはCircleShapeを指定します。ちなみにCircleShapeのほかには、RoundedCornerShapeCutCornerShapeなどを指定できます。

背景色を設定して切り抜き

Box(
    contentAlignment = Alignment.Center,
    modifier = Modifier
        .background(Color.Black)
        .size(100.dp),
) {
    Image(
        painter = painterResource(R.drawable.ic_launcher_foreground),
        contentDescription = null,
        modifier = Modifier
            .size(64.dp)
            .background(
                color = Color.Green,
                shape = CircleShape,
            )
    )
}

背景色を設定しつつ切り抜きたい場合はModifier.background()を使います。color引数に色を指定し、shape引数にCircleShapeを指定します。この例では背景が透明な画像のコンポーネントに、緑色の背景を設定し、なおかつ丸く切り抜いて表示しています。

なお、Modifier.background()colorだけを指定し、Modifier.clip()と組み合わせて使うという実装も考えられますが、これは順序によって結果が異なり、不具合のもとになるので避けた方が無難です。

Box(
    contentAlignment = Alignment.Center,
    modifier = Modifier
        .background(Color.Black)
        .size(100.dp),
) {
    Image(
        painter = painterResource(R.drawable.ic_launcher_foreground),
        contentDescription = null,
        modifier = Modifier
            .size(64.dp)
            .clip(CircleShape)
            .background(Color.Green)
    )
}

このようにclip()background()の順に書くと意図したとおりに切り抜かれますが・・・

Box(
    contentAlignment = Alignment.Center,
    modifier = Modifier
        .background(Color.Black)
        .size(100.dp),
) {
    Image(
        painter = painterResource(R.drawable.ic_launcher_foreground),
        contentDescription = null,
        modifier = Modifier
            .size(64.dp)
            .background(Color.Green)
            .clip(CircleShape)
    )
}

background()clip()の順に書くと切り抜かれません。

おそらく、background()shape引数のデフォルト値がRectangleShapeなので、clip()に指定したCircleShapeと競合しているのだと思いますが、詳しい内部動作までは確認できていません。

JetpackCompose一問一答

Jetpack Compose一問一答

コンテンツは随時追加していきます。

この記事をシェア