CoordinatorLayoutのBehaviorを自作する

この記事の概要

上記のBehaviorでは達成できない動きでも、自身でBehaviorを実装するとこんなこともできるようになるよっていうことをBehaviorの種類に合わせて紹介したいと思います。

Behaviorの種別

Behaviorを実装する上での方針です。下記のどの表現を行うかでBehaviorの実装の仕方を変えると良いです。
この記事での成果物は、GitHub[https://github.com/ttymsd/coordinator-behaviors](https://github.com/ttymsd/coordinator-behaviors)にまとめてあります。

1. CoordinatorLayout直下のViewとの相対位置を保つ

実装するもの

  • Behavior#onLayoutChild
    • CoordinatorLayout上での初期位置を指定します。
  • Behavior#layoutDependsOn
    • View(child)がどのView(dependency)との相対位置とするか決定する。
  • onDependentViewChanged
    • layoutDependsOnで対象としたViewがCoordinatorLayout上で位置が変わったときにコールバックされ、Behaviorを持つViewの位置の再レイアウトができる。

2. NestedScrollChildが実装されているViewのスクロール量に合わせて動かす

実装するもの

  • Behavior#onLayoutChild
    • CoordinatorLayout上での初期位置を指定します。
  • Behavior#onStartNestedScroll
  • Behavior#onStopNestedScroll
  • Behavior#onNestedPreFling
  • Behavior#onNestedFling
  • Behavior#onNestedPreScroll
  • Behavior#onNestedScroll
  • Behavior#onNestedScrollAccepted
    • CoordinatorLayout直下のNestedScollViewで発生したScrollEventが通知されます。

上記のメソッドを実現したい表現に合わせてOverrideしてBehaviorが設定されているViewを動かします。
Ex.BottomNavigationBehavior

3. TouchEventを処理する(Ex.CoordinatorLayout内でDragなどで移動させる)

  • Behavior#onLayoutChild
    • CoordinatorLayout上での初期位置を指定します。
  • Behavior#onInterceptTouchEvent
    • CoordinatorLayoutで発生したonInterceptTouchEventの処理が委譲されます。trueを返すと引き続きTouchEventの処理をこのBehaviorでできます。
  • Behavior#onInterceptTouchEvent
    • CoordinatorLayoutで発生しているTouchEventが委譲されているので、TouchEventを処理してViewを動かしたりします。

まとめ

いままで、CustomViewを作ってchildView等を把握してDrag処理等に合わせてLayoutしていたものが、Layout処理だけがBehaviorに切り出されることで
使い回しがしやすくなった感じを受けるのと、動かしたいView毎にBehaviorを用意することで1画面上でいろいろな動きをさせられるようになったと思う。