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?

ViewConfiguration.minimumTouchTargetSizeと近隣Composableのクリックイベントの優先順位について

Last updated at Posted at 2025-02-18

概要

ViewConfiguration.minimumTouchTargetSizeは設定された範囲内のコンポーネントの最小のタッチエリアを指定する。
コンポーネントのサイズより大きな範囲を最小のタッチエリアとして指定することもできるため、タッチエリアと近隣のコンポーネントの領域が仕組み上被りうる。
領域が被ったコンポーネントにクリックイベントが設定されている場合、ViewConfiguration.minimumTouchTargetSizeで拡張されたタッチエリアではなく近隣コンポーネントのクリックイベントが優先される。
検証している限りこの優先順位はコンポーネントの宣言順の影響は受けない。

詳細

ViewConfiguration.minimumTouchTargetSizeとは

ViewConfigurationとは、ロングプレスがタイムアウトする時間や、スクロールやスワイプの判定の閾値を設定できるinterfaceです。JetpackCpmposeのために用意されたinterfaceではなく、AndroidViewから存在しています。AndroidViewや、JetpackComposeといったレイヤの話ではなくシステム側に干渉できるinterfaceとなります。

この中にminimumTouchTargetSizeという項目があり、UIの最小タッチエリアを指定できます。デフォルトでは縦横48dpに指定されている。この48という数字はMaterial Designで指定されているタッチエリアの最小領域です。他のUIに関するinterface、例えばModifier.minimuminteractivecomponentsizeでも同様の数字が指定されており、統一的に使用されている数字だとわかります。詳しくはドキュメントを参照してください。

https://m3.material.io/foundations/designing/structure#b421e522-35a6-47cd-bfc6-bf94cbacf7bb
https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).minimumInteractiveComponentSize()

ビジュアルイメージ

赤いボックス、青いボックスを横並びに表示する。
クリックした領域に応じてトーストが表示される。

コード

以下のようなコードで、赤いボックス、青いボックスを横並びに表示する。
minimumTouchTargetSizeを縦横500dpで上書きしたViewConfigurationを使って緑のボックスを囲んでいる。

val context = LocalContext.current
val defaultViewConfiguration = LocalViewConfiguration.current

class CustomViewConfiguration : ViewConfiguration by defaultViewConfiguration {
    override val minimumTouchTargetSize: DpSize
        get() = DpSize(500.dp, 500.dp)
}

val customViewConfiguration = CustomViewConfiguration()

Row(
    modifier = Modifier.fillMaxSize(),
    verticalAlignment = Alignment.CenterVertically,
    horizontalArrangement = Arrangement.Center
) {
    Box(
        modifier = Modifier
            .size(200.dp)
            .background(Color.Blue)
            .clickable {
                Toast.makeText(
                   context, 
                     "青クリック",
                     Toast.LENGTH_SHORT
                    ).show()
                },
        )

        CompositionLocalProvider(
            LocalViewConfiguration provides customViewConfiguration
        ) {
            Box(
                modifier = Modifier
                    .size(200.dp)
                    .background(Color.Green)
                    .clickable {
                        Toast
                            .makeText(context, "緑クリック", Toast.LENGTH_SHORT)
                            .show()
                    }
            )
        }
    }

挙動

この時、青い箱以外の全ての範囲どこをクリックしても緑の箱のタッチエリアとなる。が青い箱のエリアだけはタッチエリアを奪えない。

タイトルなし.gif

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?