在CollapsingToolbarLayout / AppBarLayout中禁用垂直滚动

12

我希望CollapsingToolbarLayout / AppBarLayout仅在嵌套滚动视图中发生滚动/触摸事件时出现垂直滚动(这已经实现),但是如果用户试图直接滚动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(),但它仍然会拦截触摸事件/滚动。
3个回答

31

好的,我找到了解决方法。

你只需要在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的滚动?

如果由于Behavior为null而遇到NullPointerException,则应首先分配一个:

CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mAppbar.getLayoutParams();
params.setBehavior(new AppBarLayout.Behavior());

1
谢谢。这个可以工作,但我在方向改变时仍然有问题。你也遇到了这个问题吗? - android_eng

6

我为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上的滚动,这就是为什么我编写了第二个BindingAdapter:

@BindingAdapter("scrollable")
fun setScrollable(nestedScrollView: NestedScrollView, scrollable: Boolean) {
    nestedScrollView.setOnTouchListener { _, _ -> !scrollable }
}

0

如果您设置了任何一个app:layout_scrollFlags(例如下面的示例)- 请将其删除。

app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接