Disable vertical scroll in CollapsingToolbarLayout / AppBarLayout

前提是你 提交于 2019-12-04 09:22:03

问题


I would like the vertical scroll on the CollapsingToolbarLayout / AppBarLayout ONLY when the scroll/touch event occurs in the nestedscrollview (this is working), but if the user tries to scroll the CollapsingToolbarLayout / AppBarLayout directly it should not work. I need this because the scroll/touch events there are messing with my recyclerview scroll events.

I have this structure:

CoordinatorLayout

-- AppBarLayout

---- CollapsingToolbarLayout (scrollflags: scroll, exitUntilCollapsed, snap)

------ Toolbar (CollapseMode: pin)

------ RecyclerView (Horizontal, CollapseMode: pin)

----- /CollapsingToolbarLayout

-- /AppBarLayout

-- NestedScrollView (Behaviour: appbar_scrolling_view_behavior)

-- /NestedScrollView

/ CoordinatorLayout

I tried overriding onTouch() and onInterceptTouchEvent() for both CollapsingToolbarLayout / AppBarLayout but it keeps intercepting the touch event/scroll.


回答1:


Ok, i found out the solution for this.

You just have to override the onDrag() method in the AppBarLayout behaviour and the scroll wont be triggered if the touch occurs on top of the AppBarLayout view.

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;
    }
});

Solution from here: How to disable scrolling of AppBarLayout in CoordinatorLayout?

If you run into NullPointerException because of a null Behavior, you should assign one first:

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



回答2:


I wrote a BindingAdapter for nsL's answer:

@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
}

You can use it in a databinding layout like this:

<com.google.android.material.appbar.AppBarLayout
    ...
    app:scrollable="@{true/false}"
    ... >
...
</com.google.android.material.appbar.AppBarLayout>

In my case I also wanted to disable the scroll on the NestedScrollView, which is why I wrote a second BindingAdapter:

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



回答3:


If you have set any of app:layout_scrollFlags (example below) - delete them.

app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"


来源:https://stackoverflow.com/questions/40750005/disable-vertical-scroll-in-collapsingtoolbarlayout-appbarlayout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!