Android之解决RecyclerView与NestedScrollView的滑动冲突方法,Android,解决RecyclerView与NestedScrollView滑动冲突的方法

马肤

温馨提示:这篇文章已超过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都不能再继续向上滑动了。

Android之解决RecyclerView与NestedScrollView的滑动冲突方法,Android,解决RecyclerView与NestedScrollView滑动冲突的方法 第1张

基于这个现象,猜测recyclerView.setNestedScrollingEnabled(false)方法实际上让NestedScrollView不再将滑动事件继续向下分发,而是独自消费了这个事件,那么由于NestScrollView的高度限制(轮播图的高度和recyclerView的item高度),以及RecyclerView没有收到滑动事件(不能继续更新item数据),因此此时不能再继续向上滑动。

如果在合适的时机让NestedScrollView将事件分发给RecyclerView,即在合适的时机调用mContentList.setNestedScrollingEnabled(true),则可以解决这个问题,于是在HomePagerFragment类的initListener()方法中,为NestedScrollView设置了监听器,根据其滑动的距离为其设置是否独自消费事件。

Android之解决RecyclerView与NestedScrollView的滑动冲突方法,Android,解决RecyclerView与NestedScrollView滑动冲突的方法 第2张

解决刷新控件冲突

在解决了滑动冲突之后,将刷新控件加入项目中,项目地址:(此处插入项目地址链接)。

Android之解决RecyclerView与NestedScrollView的滑动冲突方法,Android,解决RecyclerView与NestedScrollView滑动冲突的方法 第3张

发现再次出现了问题,如图,还没拉到底呢,怎么就给我加载更多了呢?

道理是一样的,因为刷新组件TwinklingRefreshLayout消耗了事件,RecyclerView并没有收到事件,所以出现了这种情况,解决的方法是在刷新组件消耗事件的方法中进行判断,如果RecyclerView还能进行滑动,那就不消耗这个事件,将事件分发给RecyclerView,否则就消耗这个事件,进行数据的加载。

Android之解决RecyclerView与NestedScrollView的滑动冲突方法,Android,解决RecyclerView与NestedScrollView滑动冲突的方法 第4张

通过观察源码发现RefreshProcessor类重写了dispatchTouchEvent方法,在这个方法中,我们需要添加判断逻辑,首先判断子容器是否是NestedScrollView,然后进行相应的处理,代码示例如下:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    // ...原有代码...
    if (view instanceof NestedScrollView) { //这段是我添加的
        return isNestedScrollViewToBottom(view); //根据之前的分析完成方法
    } 
    // ...原有代码...
}

根据之前的分析完成方法isNestedScrollViewToBottom:

Android之解决RecyclerView与NestedScrollView的滑动冲突方法,Android,解决RecyclerView与NestedScrollView滑动冲突的方法 第5张

private static boolean isNestedScrollViewToBottom(NestedScrollView view) {
    ViewGroup viewGroup = (ViewGroup) view.getChildAt(0); //根据布局文件知道这其实是一个LinearLayout或其他ViewGroup类型容器
    RecyclerView recyclerView = null; //找到容器中的RecyclerView实例(根据实际情况实现)
    // 判断是否到达底部并返回结果(根据实际情况实现)... 省略具体实现细节... 
} 
``` 这里的实现需要根据具体的布局和逻辑来完善,至此,刷新控件冲突就解决了,不过这个方法还需要进一步的打磨和完善,以解决可能出现的问题,比如最后实现的方法需要在多种情况下进行测试和验证以确保其稳定性和可靠性。

0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码