Open3
Jetpack ComposeのGesture周りの関して

こちらの記事の下記のコードが全ての基本。
clickable
などComposeの操作関連は全て、pointerInput
が使用されている。
Modifier.pointerInput(Unit) { // このスコープはPointerInputScope
awaitEachGesture { //このスコープはAwaitPointerEventScope
awaitFirstDown() // 最初のタッチダウンイベント
do {
val event = awaitPointerEvent() // イベントが発生
// 個々のeventに対する処理
} while (event.changes.fastAny { it.pressed }) // 一つでもタッチ継続中ならループ継続
}
}

ジェスチャーの伝搬について。
Composeではジェスチャーが子→親の順番で伝搬する。
つまり適切な伝搬のキャンセル処理を記述する必要がある。
val event = awaitPointerEvent().changes // PointerInputChange
PointerInputChangeは、「操作」に関しての情報がリストで入っている。例えば、画面のどこを触っているかなど。
PointerInputChangeはそのイベントが消費されているかどうか、を表すisConsumed
というプロパティがあり、下記のようにconsume
関数を呼び出して、消費したことを伝える。
event.changes.forEach {
it.consume()
}

consume()
関数の説明には以下の記述がある。
Consumption" is just an indication of the claim and each pointer input handler implementation must manually check this flag to respect it.
つまりconsume()はただの消費されたことを表す主張であり、親側で正しくこのフラグを確認する必要がある。
つまり親側では、以下のようにキャンセルを考慮したコードを記述する必要がある。
.pointerInput(Unit) {
awaitEachGesture {
awaitFirstDown()
do {
val event = awaitPointerEvent()
val canceled = event.changes.any { it.isConsumed }
if (!canceled) {
// キャンセルされていない場合は親側の処理が必要
}
} while (event.changes.any { it.pressed })
}
}
ちなみに標準でPointerInputScope
に用意されている、detect~
という関数は当然このキャンセルに対しての考慮があるが、自分でawaitEachGesture
を使用すると、ここも考慮する必要がある