文章目录

  • 1.SnapHelper 的应用情景
  • 2.问题现象
  • 3.分析原因
  • 4.原因重点:(SnapHelper被多次创建并绑定到同一个RecyclerView)
  • 5.解决方法
    • 5.1第一种方法:
    • 5.2第二种方法:
  • 6原理剖析
  • 7源码解析:

1.SnapHelper 的应用情景

通常我们使用RecyclerView来实现简单图片轮播图Banner时,需要实现按图片翻页效果,但RecyclerView会在滚动过程中是“过程停留”无法达到“翻页”效果,这时候我们就不得不借助SnapHelper类来使得RecyclerView具备类似ViewPager“翻页”效果的能力。但随着页面UI布局的复杂性,有时候我们需要嵌套RecyclerView并结合SnapHelper。

2.问题现象

多层RecyclerView嵌套时使用SnapHelper工具类配合,向下滚动Item列表正常,但向上滚动会立即强退并杀死app程序。报错问题:“java.lang.IllegalStateException: An instance of OnFlingListener already set.”

3.分析原因

首先来了解一个概念,手指在屏幕上滑动RecyclerView然后松手,RecyclerView中的内容会顺着惯性继续往手指滑动的方向继续滚动直到停止,这个过程叫做Fling。Fling操作从手指离开屏幕瞬间被触发,在滚动停止时结束。而OnFlingListener显然就是监听Fling滚动事件的监听器。

4.原因重点:(SnapHelper被多次创建并绑定到同一个RecyclerView)

通常我们在做RecyclerView的嵌套时总会遇到这样的问题,是因为每次在onBindViewHolder中都这样写:

SnapHelper snapHelper = new PagerSnapHelper()
snapHelper.attachToRecyclerView(recyclerView)

每次滑动RecyclerView都需要重新创建SnapHelper对象并将其附着到RecyclerView上,导致一个RecyclerIView会绑定多个SnapHelper,在回头绘制RecyclerView时,会发现一个RecyclerView的SnapHelper实例(多个)重复设置,导致滚动事件出问题而退出滚动,致使整个app应用崩溃退出!

5.解决方法

5.1第一种方法:

在重新绘制RecyclerView时首先移除创建的前一个SnapHelper实例的OnFlingListener监听器。

Tips:也就是RecyclerView在第二次滑动到该位置时

Java语言

 SnapHelper snapHelper = new PagerSnapHelper()recycleView.setOnFlingListener(null)snapHelper.attachToRecyclerView(recyclerView)

Kotlin语言

val snapHelper: SnapHelper = PagerSnapHelper()
recycleView.onFlingListener = null
snapHelper.attachToRecyclerView(recyclerView)

Tips:SnapHelper通过attachToRecyclerView()方法附着到RecyclerView上,从而实现辅助RecyclerView滚动对齐操作。

5.2第二种方法:

将SnapHelper snapHelper = new
PagerSnapHelper()放在全局定义(针对类),允许类中只存在一个SnapHelper对象。每次重新绘制RecyclerView时总是调用该SnapHelper实例对象的onFlingListener。

Tips:此方法不用添加任何代码,仅需要将SnapHelper snapHelper = new
PagerSnapHelper()放在与重写方法onBindViewHolder()同级的位置。

6原理剖析

据下面的源码可以看到当与RecyclerView绑定的SnapHelper实例对象的OnFlingListener已经被设置时,再次设置系统会抛出异常:”An instance of OnFlingListener already set.“

7源码解析:

错误类型&具体错误:IllegalArgumentException:An instance of OnFlingListener already set.
 /*** Attaches the {@link SnapHelper} to the provided RecyclerView, by calling* {@link RecyclerView#setOnFlingListener(RecyclerView.OnFlingListener)}.* You can call this method with {@code null} to detach it from the current RecyclerView.** @param recyclerView The RecyclerView instance to which you want to add this helper or*                     {@code null} if you want to remove SnapHelper from the current*                     RecyclerView.** @throws IllegalArgumentException if there is already a {@link RecyclerView.OnFlingListener}* attached to the provided {@link RecyclerView}.**/
/*** Called when an instance of a {@link RecyclerView} is attached.*/private void setupCallbacks() throws IllegalStateException {if (mRecyclerView.getOnFlingListener() != null) {throw new IllegalStateException("An instance of OnFlingListener already set.");}mRecyclerView.addOnScrollListener(mScrollListener);mRecyclerView.setOnFlingListener(this);}

Android --- RecyclerViwe中使用SnapHelper报错:“An instance of OnFlingListener already set.”相关推荐

  1. android studio中连接夜神报错 adb server version doesn't match this client

    原文地址:https://blog.csdn.net/wenzhi20102321/article/details/80934037 仅用于自己做笔记 二.解决方法 解决的办法不难,就是把现在SDK版 ...

  2. 【错误记录】Android Studio 中 Gradle 配置报错 ( Can‘t determine type for tag ‘<item name=““ type=“String“>)

    文章目录 一.报错信息 二.解决方案 一.报错信息 在 Android Studio 工程的 build.gradle 中的 " android # defaultConfig " ...

  3. java 更新ui_你怎么解决Android开发中更新UI报错的异常吗-百度经验

    执行上述代码. 在App中点击"变透明"的按钮后,App就退出了. logcat中打印了这个错: 03-20 14:47:31.326 11640-11796/com.exampl ...

  4. Android Studio中R文件报错的解决方案

    1.说明 平时呢,我们运行项目的时候.会不小心就出现R文件变红的情况,尽管我们是无心的,但是这种问题太烦恼了,有时处理不好整项目都无法运行,确实给像我这样菜鸟带来了很大的烦恼;这里我提供一种解决方案, ...

  5. Android studio 中使用xUtils报错

    2019独角兽企业重金招聘Python工程师标准>>> Error:(53, 35) 错误: 无法访问HttpRequestBase 找不到org.apache.http.clien ...

  6. Android Studio中虚拟机运行时报错的解决方法

    Android Studio中启动虚拟机时,在主界面的"Event Log"中可能会有报错信息,此时虚拟机仍然是可以运行的. 1 Failed to open /qemu.conf ...

  7. 【错误记录】Android Studio 打包 apk 文件报错 ( The destination folder does not exist or is not writeable )

    文章目录 一.报错信息 二.解决方案 一.报错信息 在 Android Studio 工程中 , 打包 APK 文件时 , 报错 ; Android Studio 打包 apk 文件报错 : The ...

  8. 《一起学习rgbdSLAM》中g2o部分报错的问题

    <一起学习rgbdSLAM>中g2o部分报错的问题 在高博的<一起学习rgbdSLAM>第六讲中使用到了g2o工具.但是由于版本问题,按照高博的写法来编写代码在编译过程中会报错 ...

  9. anconda安装后命令行中安装tensorflow报错

    现象  anconda安装后命令行中安装tensorflow报错 pip install --upgrade --ignore-installed tensorflow-gpu Building wh ...

最新文章

  1. Linux虚拟文件系统简介
  2. Java中使用Jedis连接Redis对Key进行操作的常用命令
  3. 吴恩达 coursera AI 第二课总结+作业答案
  4. 解惑:如何使用html+css+js实现旋转相册,立方体相册等动画效果
  5. 第二十二篇 玩转数据结构——构建动态数组
  6. 数学特级老师:数学除了做习题,这份140G的资料一定要收藏!
  7. python常用字符串处理函数_Python第10课:常用的字符串处理函数
  8. 作者:Ochora Dennis Reagan(1990-),男,东北大学软件学院硕士生
  9. 安装GIT,集成到Powershell中
  10. 纺大数学与计算机学院徐涛,数学与统计学院
  11. win10系统电脑提示此程序被组策略阻止的解决办法
  12. ECSHOP和SHOPEX快递单号查询中通插件V8.6专版
  13. 「游戏」c++贪吃蛇1.1
  14. 解决图片放在src上面加载不出来,但是放在浏览器地址可以访问
  15. 微信小程序获取并修改app.js中的值
  16. photoshop基本的操作
  17. 软件工程 -- 系统流程图
  18. errno和perror
  19. 白盒测试与黑盒测试的比较
  20. IoT设备与手机App之间如何实现实时消息通信——业务场景最佳实践

热门文章

  1. Android非UI线程更新UI的几种方法
  2. The maximum string content length quota (8192) has been exceeded while reading XML data
  3. Npm的配置管理及设置代理
  4. 免费版最好用功能强大方便快捷的计算器Calculator#出炉~
  5. 如何在Simulink中添加延迟环节
  6. 一分钟了解 Matlab求两个矩阵的相关程度corr2
  7. Linux使用tcpdump抓取网络数据包示例
  8. Ice笔记--C++线程与并发(小结)
  9. python animation 轨迹_Python实例:自动轨迹绘制
  10. CSS中可以or不可以继承的属性