0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Jetpack Composeで角丸カードからリップルがはみ出した時の対応

0
Posted at

はじめに

一覧を角丸のカードにまとめ、各行をタップできるようにしました。通常時はきれいな角丸です。しかし、一番上や一番下の行を押すと、タップ時のリップルがカードの角より外側に見えました。

原因は、背景を角丸で描くことと、子要素の描画を角丸に収めることが別だったためです。

背景だけを角丸にしていた

最初の構成を小さくすると、次のようになります。

  @Composable
  fun ItemList(items: List<String>, onItemClick: (String) -> Unit) {
      val shape = RoundedCornerShape(12.dp)

      Column(
          modifier = Modifier
              .fillMaxWidth()
              .background(Color(0xFFF2F2F2), shape),
      ) {
          items.forEach { item ->
              Text(
                  text = item,
                  modifier = Modifier
                      .fillMaxWidth()
                      .clickable { onItemClick(item) }
                      .padding(16.dp),
              )
          }
      }
  }

background(..., shape) は背景を指定した形で描きます。一方、行の clickable が表示するリップルまで、その形で切り取る指定ではありません。Android Developers の Modifier 一覧
(https://developer.android.com/develop/ui/compose/modifiers-list)でも、background は背景の描画、clip は内容の切り取りとして別々に定義されています。

親の Column をクリップする

カード全体の角丸に子要素の描画も合わせたいので、親に clip を追加します。

  @Composable
  fun ItemList(items: List<String>, onItemClick: (String) -> Unit) {
      val shape = RoundedCornerShape(12.dp)

      Column(
          modifier = Modifier
              .fillMaxWidth()
              .clip(shape)
              .background(Color(0xFFF2F2F2), shape),
      ) {
          items.forEach { item ->
              Text(
                  text = item,
                  modifier = Modifier
                      .fillMaxWidth()
                      .clickable { onItemClick(item) }
                      .padding(16.dp),
              )
          }
      }
  }

これで、一番上と一番下の行から出るリップルも、親の角丸の内側に収まります。元になった修正も、親の Column に clip(RoundedCornerShape(...)) を1行追加するものでした。

ポイントは Modifier の順序です。Compose では、同じ Modifier でも並べる順序によって結果が変わります。公式ドキュメント
(https://developer.android.com/develop/ui/compose/modifiers)には、clickable と padding
の順序でタップ可能な範囲が変わる例があります。見た目、リップル、余白の範囲をそれぞれ意識して並べる必要があります。

確認するときは角を押す

カードの中央の行を押しても、この問題は見つけにくいです。確認するなら、次の場所を長押ししてリップルを見るのが確実です。

  • 一番上の行の左上・右上
  • 一番下の行の左下・右下
  • 区切り線や子要素も、意図した範囲に収まっているか

background(shape) だけで角丸のカードが完成したように見えても、子要素のタップ表現まで確認しておくと安心です。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?