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?

Compose でドラッグ操作と縦スクロールを共存させる

0
Last updated at Posted at 2026-07-19

はじめに

以前の記事Jetpack Compose で Google Map内の操作と縦スクロールを共存させるでは、マップやグラフにタッチしている間だけ親のスクロールを無効にする方法を紹介しました。
前回の実装でタップ操作との共存はできたのですが、ドラッグ操作を加えたところ別の問題が起きたので紹介します。

前回のおさらい

タッチ中はスクロールを無効にするフラグを立て、verticalScrollenabled で制御するパターンでした。

  var isTouched by remember { mutableStateOf(false) }
                                                                                                    
  Column(modifier = Modifier.verticalScroll(scrollState, enabled = !isTouched)) {
      MyChart(onTouchChanged = { isTouched = it })                                                  
  } 

今回の問題

グラフ上で指をなぞる(ドラッグしてバーを選択する)操作を追加したところ、ドラッグ中に指を少し縦に動かすと親のスクロールが反応してしまう問題が起きました。

前回のフラグで verticalScrollは無効にしているはずなのになぜ?と思いましたが、原因は別のところにありました。

原因

onDrag コールバック内ではポインターイベントを消費していないためです。
Compose のジェスチャー処理はイベントが消費されていない場合、親のコンポーザブルにもそのイベントが伝播します。verticalScroll を無効にしていても、伝播したイベントが別の経路でスクロールを動かしてしまっていました。

解決策

結論から言いますと、change.consume() を呼ぶことです。
onDrag 内で change.consume() を呼ぶだけで解決します。

  Modifier.pointerInput(values) {                                                                   
      detectDragGesturesAfterLongPress(                                                             
          onDragStart = { ... },
          onDrag = { change, _ ->                                                                   
              change.consume()  // ← これで親への伝播を止める                                     
              val slot = barIndexFromOffset(change.position.x, ...)                                 
              selectedSlot = slot                                                                   
          },                                                                                        
      )                                                                                             
  }   

これでドラッグ中のポインターイベントが処理済みとしてマークされ、親への伝播が止まります。
また、 前回のタッチフラグと今回の consume() は役割が異なるため、両方必要です。

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?