温馨提示:这篇文章已超过422天没有更新,请注意相关的内容是否还可用!
摘要:在Android开发中,解决RecyclerView与NestedScrollView之间的滑动冲突是一个常见问题。冲突主要源于两者都是可滚动的视图,导致交互时的冲突。解决此问题的方法包括使用事件拦截机制、自定义行为以及特定的布局调整。通过调整滚动方向、设置触摸模式或结合其他布局元素,可以有效解决滑动冲突,提升用户体验。
当我们滑动RecyclerView组件时,上方的轮播图并没有进行滑动(NestedScrollView没有滑动,即滑动事件被RecyclerView消费了),当RecyclerView滑到底时,轮播图部分才进行滑动,如图,RecyclerView已经进行了滑动,但轮播图部分没有。
整体布局代码:
(此处插入图片)
这不符合我们的设计要求,我们希望让轮播图先滑到顶部,然后才进行RecycleView的滑动,在recycleView中,使用recyclerView.setNestedScrollingEnabled(false)方法可以解决滑动冲突,进行测试的代码为:
@BindView(R.id.home_pager_content_list) public RecyclerView mContentList; @Override protected void initView(View rootView) { mContentList.setNestedScrollingEnabled(false); //确实可以解决滑动冲突 }
测试后发现可行,但是出现了另一个问题,当轮播图部分滑动出屏幕时,就不能继续向上滑动了,如图,此时无论是NestedScrollView还是RecyclerView都不能再继续向上滑动了。
基于这个现象,猜测recyclerView.setNestedScrollingEnabled(false)方法实际上让NestedScrollView不再将滑动事件继续向下分发,而是独自消费了这个事件,那么由于NestScrollView的高度限制(轮播图的高度和recyclerView的item高度),以及RecyclerView没有收到滑动事件(不能继续更新item数据),因此此时不能再继续向上滑动。
如果在合适的时机让NestedScrollView将事件分发给RecyclerView,即在合适的时机调用mContentList.setNestedScrollingEnabled(true),则可以解决这个问题,于是在HomePagerFragment类的initListener()方法中,为NestedScrollView设置了监听器,根据其滑动的距离为其设置是否独自消费事件。
解决刷新控件冲突
在解决了滑动冲突之后,将刷新控件加入项目中,项目地址:(此处插入项目地址链接)。
发现再次出现了问题,如图,还没拉到底呢,怎么就给我加载更多了呢?
道理是一样的,因为刷新组件TwinklingRefreshLayout消耗了事件,RecyclerView并没有收到事件,所以出现了这种情况,解决的方法是在刷新组件消耗事件的方法中进行判断,如果RecyclerView还能进行滑动,那就不消耗这个事件,将事件分发给RecyclerView,否则就消耗这个事件,进行数据的加载。
通过观察源码发现RefreshProcessor类重写了dispatchTouchEvent方法,在这个方法中,我们需要添加判断逻辑,首先判断子容器是否是NestedScrollView,然后进行相应的处理,代码示例如下:
@Override public boolean dispatchTouchEvent(MotionEvent ev) { // ...原有代码... if (view instanceof NestedScrollView) { //这段是我添加的 return isNestedScrollViewToBottom(view); //根据之前的分析完成方法 } // ...原有代码... }
根据之前的分析完成方法isNestedScrollViewToBottom:
private static boolean isNestedScrollViewToBottom(NestedScrollView view) { ViewGroup viewGroup = (ViewGroup) view.getChildAt(0); //根据布局文件知道这其实是一个LinearLayout或其他ViewGroup类型容器 RecyclerView recyclerView = null; //找到容器中的RecyclerView实例(根据实际情况实现) // 判断是否到达底部并返回结果(根据实际情况实现)... 省略具体实现细节... } ``` 这里的实现需要根据具体的布局和逻辑来完善,至此,刷新控件冲突就解决了,不过这个方法还需要进一步的打磨和完善,以解决可能出现的问题,比如最后实现的方法需要在多种情况下进行测试和验证以确保其稳定性和可靠性。
还没有评论,来说两句吧...