CollapsingToolbarLayout/AppBarLayoutの垂直スクロールは、nestedscrollviewでscroll/touchイベントが発生した場合にのみ必要です(これは機能しています)が、ユーザーがCollapsingToolbarLayout/AppBarLayoutを直接スクロールしようとすると機能しません。スクロール/タッチイベントがrecyclerviewスクロールイベントを台無しにしているので、これが必要です。
私はこの構造を持っています:
CoordinatorLayout
-- AppBarLayout
---- CollapsingToolbarLayout (scrollflags: scroll, exitUntilCollapsed, snap)
------ Toolbar (CollapseMode: pin)
------ RecyclerView (Horizontal, CollapseMode: pin)
----- /CollapsingToolbarLayout
-- /AppBarLayout
-- NestedScrollView (Behaviour: appbar_scrolling_view_behavior)
-- /NestedScrollView
/ CoordinatorLayout
CollapsingToolbarLayout/AppBarLayoutの両方でonTouch()とonInterceptTouchEvent()をオーバーライドしようとしましたが、タッチイベント/スクロールをインターセプトし続けます。
わかりました、私はこれの解決策を見つけました。
AppBarLayoutビヘイビアーのonDrag()メソッドをオーバーライドするだけで、AppBarLayoutビューの上でタッチが発生してもスクロールはトリガーされません。
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
@Override
public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
return false;
}
});
ここからの解決策: CoordinatorLayoutでAppBarLayoutのスクロールを無効にする方法は?
Null動作が原因でNullPointerExceptionが発生した場合は、最初に1つ割り当てる必要があります。
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mAppbar.getLayoutParams();
params.setBehavior(new AppBarLayout.Behavior());
私はnsLの答えのためにBindingAdapterを書きました:
@BindingAdapter("scrollable")
fun setScrollable(appBarLayout: AppBarLayout, scrollable: Boolean) {
val layoutParams = appBarLayout.layoutParams as CoordinatorLayout.LayoutParams
val behavior = (layoutParams.behavior as? AppBarLayout.Behavior) ?: AppBarLayout.Behavior()
behavior.setDragCallback(object : AppBarLayout.Behavior.DragCallback() {
override fun canDrag(appBarLayout: AppBarLayout): Boolean = scrollable
})
layoutParams.behavior = behavior
}
次のようなデータバインディングレイアウトで使用できます。
<com.google.Android.material.appbar.AppBarLayout
...
app:scrollable="@{true/false}"
... >
...
</com.google.Android.material.appbar.AppBarLayout>
私の場合、NestedScrollViewのスクロールも無効にしたかったので、2番目のBindingAdapterを作成しました。
@BindingAdapter("scrollable")
fun setScrollable(nestedScrollView: NestedScrollView, scrollable: Boolean) {
nestedScrollView.setOnTouchListener { _, _ -> !scrollable }
}
app:layout_scrollFlags
(以下の例)のいずれかを設定した場合は、それらを削除します。
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"