LoginSignup
1
3

More than 5 years have passed since last update.

AppBarLayoutで縦スクロール

Last updated at Posted at 2018-07-14

AppBarLayoutにViewPagerを入れてその中にNestedScrollViewやRecyclerViewで縦スクロールしたい場合、そのまま配置しただけではスクロールした際にAppBarLayoutの縦スクロールが優先されてしまい、内包するコンポーネントのスクロールが動作しませんでした。

やったこと

Viewが階層構造になってる際に子ViewにOnTouchListenerが設定されていないと親Viewにイベントが伝搬されるため、対象のViewにOnTouchListenerを設定し、requestDisallowInterceptTouchEventで親Viewへの伝搬を止めることで実現できました。
ただし、ViewPagerの中にある場合は横スクロールを止めるわけにはいかないので縦スクロールを判定できた場合のみ伝搬を止めています。

val minDistance = 100
var downY: Float = 0F
var upY: Float = 0F

nestedScrollView.setOnTouchListener(View.OnTouchListener { v, event ->
    when (event.action) {
        MotionEvent.ACTION_DOWN -> {
            downY = event.y
            return@OnTouchListener true
        }
        MotionEvent.ACTION_UP -> {
            upY = event.y
            return@OnTouchListener true
        }
    }
    val deltaY = downY - upY
    if (Math.abs(deltaY) > minDistance) {
        // 一定以上縦方向にスワイプした場合は親に対してタッチイベントを伝搬しない
        // これによりAppBarLayoutのスクロールと競合せずにスクロールできるようになる
        v.parent.requestDisallowInterceptTouchEvent(true)
    }
    return@OnTouchListener false
}

サンプル

misoca12/VerticalScrollInAppBarLayout

参考

https://stackoverflow.com/questions/7449799/how-are-android-touch-events-delivered
https://qiita.com/takahirom/items/2978ede8e7d40b888832
http://blog.lciel.jp/blog/2013/12/03/android-touch-event

1
3
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
1
3