形状にクリップされた画像を表示する

切り抜かれた図形に画像を合わせ、図形の周囲に影を描画して立体感を演出できます。この手法は、アバターや商品のサムネイルなどのデザインを作成する際や、カスタム シェイプでロゴを表示する際に便利です。

画像をシェイプに切り抜いて表示するには、次の操作を行う必要があります。

  • シェイプを作成します。
  • 画像を図形にクリップします。

バージョンの互換性

この実装では、プロジェクトの minSDK を API レベル 21 以上に設定する必要があります。

依存関係

図形を作成する

次のコードは、丸いポリゴンを動的に描画してレンダリングできるカスタムシェイプを作成します。

fun RoundedPolygon.getBounds() = calculateBounds().let { Rect(it[0], it[1], it[2], it[3]) }
class RoundedPolygonShape(
    private val polygon: RoundedPolygon,
    private var matrix: Matrix = Matrix()
) : Shape {
    private var path = Path()
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        path.rewind()
        path = polygon.toPath().asComposePath()
        matrix.reset()
        val bounds = polygon.getBounds()
        val maxDimension = max(bounds.width, bounds.height)
        matrix.scale(size.width / maxDimension, size.height / maxDimension)
        matrix.translate(-bounds.left, -bounds.top)

        path.transform(matrix)
        return Outline.Generic(path)
    }
}

コードに関する主なポイント

  • RoundedPolygon.getBounds() は、境界を計算する拡張関数を RoundedPolygon クラスに定義します。
  • RoundedPolygonShape クラスは Shape インターフェースを実装しているため、Jetpack Compose でカスタム形状(丸いポリゴン)を定義できます。
  • このシェイプは Matrix を使用して、柔軟なレンダリングのためにスケーリング オペレーションと変換オペレーションを管理します。
  • createOutline() 関数は RoundedPolygon オブジェクトを受け取り、指定されたサイズ内に収まるようにスケーリングして変換し、描画される最終的なシェイプを記述する Outline オブジェクトを返します。

画像をシェイプにクリップする

次のコードは、画像を六角形に切り抜き、微妙なドロップシャドウを追加して奥行き感を演出します。

val hexagon = remember {
    RoundedPolygon(
        6,
        rounding = CornerRounding(0.2f)
    )
}
val clip = remember(hexagon) {
    RoundedPolygonShape(polygon = hexagon)
}
Box(
    modifier = Modifier
        .clip(clip)
        .background(MaterialTheme.colorScheme.secondary)
        .size(200.dp)
) {
    Text(
        "Hello Compose",
        color = MaterialTheme.colorScheme.onSecondary,
        modifier = Modifier.align(Alignment.Center)
    )
}

コードに関する主なポイント

  • RoundedPolygon オブジェクトと RoundedPolygonShape オブジェクトは、六角形を定義して画像に適用するために使用します。
  • このコードでは、graphicsLayer を使用して、地形に基づくシャドウを画像に追加しています。これにより、奥行き感と背景からの視覚的な分離感が生まれます。
  • remember ブロックを使用すると、シェイプとクリッピングの定義が 1 回だけ計算され、後で UI を再コンポーズする際に記憶されるため、パフォーマンスが最適化されます。

結果

六角形の犬(縁にシャドウを適用)
図 1. クリップとして適用されたカスタム シェイプ。

このガイドを含むコレクション

このガイドは、Android 開発の幅広い目標を網羅する、厳選されたクイックガイド コレクションの一部です。

明るく魅力的なビジュアルを使用して、Android アプリの外観を美しくする手法について学びます。

ご質問やフィードバックがある場合

よくある質問のページでクイックガイドをご覧になるか、お問い合わせフォームからご意見をお寄せください。