探索医疗人工智能的深水区!依图医疗向世界展示中国医疗人工智能成果
06-18
RecyclerView嵌套滑顶项目应该说是很糟糕,但是如果项目确实需要这样的结构应用到首页上,想要找到成熟的解决方案并不容易。 。
本文给出了稳定运行半年多的嵌套滑动代码。代码地址:ByRecyclerView/stickyrv 渲染体验地址 fir.im 下载项目源码 半年前接到的任务,需要把首页改成和天猫或者京东一样。
现在看来,滑到顶部已经是标配了。我之前在网上看到过。
类似的文章还有很多,应该不难找到。然而我搜遍了几乎所有的文章和项目,基本上都无法使用。
存在卡住的错误。我问作者是否已应用到项目中,但没有回复。
原本以为之前的滑动顶部会以CoordinatorLayout+TabLayout+RecyclerView的形式来处理,但是感觉不合适。我用uiautomatorviewer分析发现天猫/京东/网易考拉所有app的首页都是RecyclerView-ViewPager-RecyclerView的形式,然后继续搜索找到了最接近的项目xmuSistone/PersistentRecyclerView。
这应该是我找到的最完整的代码了。应用到实际项目中后,发现仍然存在问题: 1、在华为设备上滑动子RecyclerView时会出现跳转。
2、父RecyclerView使用SmartRefreshLayout进行下拉刷新。有问题,也有回应。
卡顿 3. Sub-RecyclerView 加载较多,需要处理 4. Sub-RecyclerView 嵌套横向 RecyclerView 滑动冲突问题 5. Android 4.4 惯性滑动崩溃问题 当然,滚轮并不能完美契合项目的需求,所以有些上面修改了代码。改进1.在华为设备上,滑动子RecyclerView时出现跳转问题。
我在几位作者写的滑动到顶部的代码中发现了它。在其他手机上是没有问题的。
原因是华为设备非常敏感,手指放置时无法移动。很容易在ChildRecyclerView中触发parent.requestDisallowInterceptTouchEvent(false),并将事件抛给ParentRecyclerView,造成卡顿。
处理方法是在dispatchTouchEvent中如果垂直滑动距离超过24f则抛给ParentRecyclerView。具体代码: 代码语言: javascript copy override fun dispatchTouchEvent(e: MotionEvent): Boolean { val x = e.rawX val y = e.rawY when (e.action) { MotionEvent.ACTION_DOWN -> { //按下时的坐标storage downX = x downY = y // true表示ParentRecyclerView不拦截parent.requestDisallowInterceptTouchEvent(true) } MotionEvent.ACTION_MOVE -> { //获取距离差 val dx: Float = x - downX val dy: Float = y - downY // 通过距离差确定方向 valorientation = getOrientation(dx, dy) vallocation = intArrayOf(0, 0) getLocationOnScreen(location) when (orientation) { "d" -> if (canScrollVertically(-1)) { // 让ParentRecyclerView在可以下滑的时候不拦截parent.requestDisallowInterceptTouchEvent(true) } else { //当内部RecyclerView下拉到顶部时 if(dy < 24f){// 如果滑动距离小于这个值,Parent仍然不会拦截parent.requestDisallowInterceptTouchEvent(true) }else{ // 向Parent抛出滑动事件,使其可以随着Parent滑动parent.requestDisallowInterceptTouchEvent(false) ) } } "u" -> { // 向上滑动时,始终由ChildRecyclerView处理parent.requestDisallowInterceptTouchEvent(true) } } } } return super.dispatchTouchEvent(e)}private fun getOrientation(dx: Float, dy: Float ): String { return if (Math .abs(dx) > Math.abs(dy)) { //X轴移动 if (dx > 0) "r" else "l" //右、左} else { / /Y轴移动 if (dy > 0 ) "d" else "u" //Down//Up}} 2.解决下拉刷新/上拉加载问题(问题2/3)因为我花了一个之前花了不少功夫写ByRecyclerView,支持下拉刷新和上拉加载。
,其本质是在Adapter中添加一个特殊的viewType进行处理,这样就带来了更好的兼容性,所以BaseRecyclerView继承了ByRecyclerView。已满足要求。
只需要分别为ParentRecyclerView和ChildRecyclerView添加下拉刷新和上拉加载监听即可: 代码语言:javascript copy ParentRecyclerView.setOnRefreshListener { }childRecyclerView.setOnLoadMoreListener { } 3.子RecyclerView中的item水平嵌套 RecyclerView 这部分滑动冲突问题比嵌套top处理简单很多: 代码语言:javascript copy override fundispatchTouchEvent(e: MotionEvent): Boolean { val x = e.rawX val y = e.rawY when (e.action ) { MotionEvent.ACTION_DOWN - > { downX = x downY = y } MotionEvent.ACTION_MOVE -> { // 获取距离差 val dx: Float = x - downX val dy: Float = y - downY // 通过距离差确定方向 valorientation = getOrientation (dx, dy) val location = intArrayOf(0, 0) getLocationOnScreen(location) when (orientation) { // 上下滑动时扔给ChildRecyclerView处理 "d" ->parent.requestDisallowInterceptTouchEvent(false) "u" -> 父.requestDisallowInterceptTouchEvent(false) "r" -> { if (canScrollVertically(-1)) { // 当可以向右滑动时,自己处理。内部可以左右滑动parent.requestDisallowInterceptTouchEvent(true) } else { // 当你右滑到顶部的时候,交给parent来处理,这样就可以滑动到ViewPager的下一个位置了parent.requestDisallowInterceptTouchEvent(false) } } "l" -> { if (canScrollVertically(-1)) {parent.requestDisallowInterceptTouchEvent(true) } else {parent.requestDisallowInterceptTouchEvent (false) } } } } } return super.dispatchTouchEvent(e)} 4. Android 4.4 之后网上发布了惯性滑动崩溃问题,发现Android 4.4手机惯性滑动停止后肯定会崩溃。
具体原因是API 21中添加了onNestedScrollAccepted(),在较低的API级别中不能使用它,因为由于使用这个版本的人很少,所以我们做了一个粗略的工作:代码语言:javascript copy override fun onNestedPreFling(target: View,velocityX:Float,velocityY:Float):Boolean { try { if (android.os.Build .VERSION .SDK_INT <= 19) { return true } return super.onNestedPreFling(target,velocityX,velocityY) } catch (e: Exception) { return true } } 总结 本项目是在PersistentRecyclerView中开发修改的,解决了一些问题顿兼容性问题并增加了下拉刷新和上拉加载功能,并且经过一段时间的大规模使用,已经基本稳定,使用起来更加方便。项目代码放在ByRecyclerView/stickyrv中,因为不是必须的功能,所以没有放置library,如果需要使用的话,自己复制代码即可。
如果您有任何疑问,请提出问题。再次感谢作者的开源精神。
版权声明:本文内容由互联网用户自发贡献,本站不拥有所有权,不承担相关法律责任。如果发现本站有涉嫌抄袭的内容,欢迎发送邮件 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
标签:
相关文章
06-18
06-18
06-18
06-18
06-08
最新文章
【玩转GPU】ControlNet初学者生存指南
【实战】获取小程序中用户的城市信息(附源码)
包雪雪简单介绍Vue.js:开学
Go进阶:使用Gin框架简单实现服务端渲染
线程池介绍及实际案例分享
JMeter 注释 18 - JMeter 常用配置组件介绍
基于Sentry的大数据权限解决方案
【云+社区年度征文集】GPE监控介绍及使用