web-dev-qa-db-ja.com

CollapsingToolbarLayout / AppBarLayoutで垂直スクロールを無効にする

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()をオーバーライドしようとしましたが、タッチイベント/スクロールをインターセプトし続けます。

11
nsL

わかりました、私はこれの解決策を見つけました。

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());
28
nsL

私は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 }
}
2
monkey

app:layout_scrollFlags(以下の例)のいずれかを設定した場合は、それらを削除します。

app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
0
Morteza Rastgoo