android在嵌套滑动的时候会产生滑动冲突。之前我也碰到,但是以前的笔记本丢失了,所以只能重新再写一章。

一.会产生滑动冲突的情况

那么什么时候会产生滑动冲突呢?比如你有个activity,activity的上半部分是一个布局,下半部分是一个可滑动控件(RecyclerView、ListView等),或者下半部分是个viewpager,里面的fragment布局是一个可滑动控件,这样的页面就会产生滑动冲突。

二.以前的做法

虽然我以前的笔记丢失了,但是当时的解决问题的思路我依然记得。
(1)重写一个viewpager继承系统的ViewPager,至于怎么重写的我不太记得了
(2)重写RecyclerView继承系统的RecyclerView,因为我记得会出现高度的原因导致RecyclerView不设置固定高度的话会不显示或者只显示一个Item,所以要重写RecyclerView去动态衡量Item x count 的高度。
当时虽然能解决,但是最后的效果很变扭。

三.现在的做法

现在我肯定不会像之前一样做,因为出了一个新控件NestedScrollView。它能够很好的帮我们解决滑动冲突,接下来我会尽我所能分析所有可能出现的情况。

1.布局只嵌套RecyclerView的情况

就是如下图的情况:

image.png

这种情况最容易解决,就直接使用NestedScrollView做父布局,然后嵌套RecyclerView就行。

<android.support.v4.widget.NestedScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/m_nsv"android:fillViewport="true"xmlns:android="http://schemas.android.com/apk/res/android"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="150dp"android:text="Hello World!" /><android.support.v7.widget.RecyclerViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/c_rv"></android.support.v7.widget.RecyclerView></LinearLayout></android.support.v4.widget.NestedScrollView>

这样就行,切记要记住两点:
(1)在父布局NestedScrollView加android:fillViewport="true",然后RecyclerView会不显示出来,不显示出来的原因是RecyclerView是一个动态展示的View,而直接使用的话用我之前说的话叫做会被压扁,所以加这个属性让子View显示match_parent的效果。
(2)有的人说要给RecyclerView设setNestedScrollingEnabled(false),不然滑动时会卡,这个我没试过,我设的是true,目前感觉滑动时没什么影响。

2.布局嵌套其它可滚动控件的情况

就是在第一种情况下把RecyclerView换成其它可滑动控件。
直接说吧,你要用NestedScrollView才有用,原因是解决滑动冲突的关键在于NestedScrollingParent和NestedScrollingChild两个接口(下面会详细说)
而RecyclerView和NestedScrollView都实现NestedScrollingChild接口,并在内部封装了解决滑动冲突的逻辑处理,所以只有NestedScrollView直接嵌套RecyclerView或NestedScrollView不会产生滑动冲突。
NestedScrollView的用法和RecyclerView一样,记得加那些属性。

3.布局嵌套ViewPager,ViewPager嵌套RecyclerView等可滑动控件的情况

这种情况处理起来比较麻烦,而很多人都是碰到这种情况。如下图:

image.png

其实我之前写过一篇文章能解决这种情况,那就是使用CoordinatorLayout,使用CoordinatorLayout能解决这种情况。
但是,我文章里也说过了,CoordinatorLayout有BUG,使用起来卡得像坨屎一样,不管你能不能忍,反正我是不能忍,所以我不会使用CoordinatorLayout。

不用CoordinatorLayout还有以下三种解决办法:
(1)使用github上面开源的那个自定义CoordinatorLayout来解决,叫什么我忘了。

但是我们老大说了,最好别用别人的开源View。于是我只能用第二种方法。

(2)放弃使用ViewPager
为什么,因为系统的ViewPager做不到,上面有说到能解决冲突是因为NestedScrollingParent和NestedScrollingChild,并且NestedScrollingChild的ViewGroup要是实现NestedScrollingParent接口的View,NestedScrollingParent的ChildView要是实现NestedScrollingChild接口的View。
而图中的父布局和RecyclerView隔着一个ViewPager,也就是说NestedScrollingParent的ChildView是ViewPager,NestedScrollingChild的ViewGroup是ViewPager。所以说直接嵌套一层ViewPager的情况是无法解决滑动冲突的。
那有一个很直接的办法就是不用ViewPager,用FragmentManager,这样就能实现解决滑动冲突。

<android.support.v4.widget.NestedScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"xmlns:app="http://schemas.android.com/apk/res-auto"android:fillViewport="true"android:id="@+id/nsv"app:layout_behavior="@string/appbar_scrolling_view_behavior"xmlns:android="http://schemas.android.com/apk/res/android"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:descendantFocusability="blocksDescendants"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/white"android:orientation="horizontal"android:minHeight="10dp"android:padding="10dp"android:id="@+id/ll_header">.........................................</LinearLayout></LinearLayout><android.support.v4.widget.NestedScrollViewandroid:layout_marginTop="15dp"android:layout_width="match_parent"android:layout_height="match_parent"android:fillViewport="true"android:id="@+id/c_nsv"><FrameLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/fl_content"></FrameLayout></android.support.v4.widget.NestedScrollView></LinearLayout></android.support.v4.widget.NestedScrollView>

这里的FrameLayout就是给FragmentManager来显示FrameLayout。
这样做就能解决一个activity多个fragment的情况下的滑动冲突。

但是有的朋友说不嘛,我就要Viewpager,我就要酷酷的滑动动画效果。唉,那你就用最实在的第三中方法吧。

(3)自定义
没办法了,那就用自定义吧,自定义一个VIewGroup实现NestedScrollingParent接口,然后自定义一个View实现NestedScrollingChild接口。或者你可以外层使用NestedScrollView,内层自定义ViewPager来实现NestedScrollingChild接口。

你以为这样就完啦?当然没这么简单。在NestedScrollingChild接口中有这些方法。

image.png

你需要在这些方法里面自己写上处理滑动冲突的逻辑,你可以参考RecyclerView的去写,也可以在网上找,网上有一些大神是真的有介绍,但也有一些人要么瞎JB抄别人的又不抄完,要么只会说用CoordinatorLayout。我其实也不是很会里面的细节处理,只是知道流程而已,所以也不装X了。

四.其它使用时的问题

并非解决滑动冲突就没有其它问题。

1.NestedScrollView(RecyclerView)重新加载数据时会自动滚动到底部。

如果你碰到这种情况,只要给父布局的NestedScrollView设.scrollTo(0, 0)就行,和ScrollView一样的。

2.禁止滑动。

如果你想在某些情况下禁止NestedScrollView滑动,可以像处理ScrollView一样,在父布局的NestedScrollView加入监听,例如我这:

public void isScroll(boolean bol){Nsv.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {return !bol;}});}

这个方法是设置可滑动和不可滑动。

3.记得设android:fillViewport="true"

如果你嵌套的布局没有显示,那有可能你忘了给父布局NestedScrollView设置android:fillViewport属性。

目前就碰到这些问题,有什么以后再接着补充吧。

Android嵌套滑动冲突相关推荐

  1. 一种嵌套滑动冲突的解决方案

    非嵌套滑动 | 嵌套滑动 相比起非嵌套滑动的自定义分发事件的方案,嵌套滑动冲突有比较成熟的 Google 解决方案:NestedScrolling . 三层嵌套的滑动冲突 UI 层级如下: 最外层(底 ...

  2. android控件的touch事件_聊聊Android嵌套滑动

    聊聊Android嵌套滑动 最近工作中遇到了需求是使用 Bottom-Sheet 交互的弹窗,使用了 design 包里面的 CoordinatorLayout 和 BottomSheetBehavi ...

  3. Android仿小米时钟嵌套滑动(NestedScroll, 自定义behavior)

    最近无聊刷手机的时候, 发现小米时钟的嵌套滑动很有意思, 就试着做了下 先上对比图: 分析下小米时钟的滑动 闹钟列表 向上滑动时, 时钟面 透明度上升, 快到最大滑动时逐渐显示数字时钟. 在闹钟列表向 ...

  4. 自定义控件(视图)2期笔记13:View的滑动冲突之 内部拦截法

    1. 内部拦截法: 父容器不拦截事件,所有的事件全部都传递给子元素,如果子元素需要此事件就直接消耗掉,否则就交给父容器进行处理. 这种方法和Android中的事件分发机制不一样,需要配合request ...

  5. Android之解决ScrollView嵌套RecycleView导致滑动冲突或者显示不全的问题

    1 问题 ScrollView嵌套RecycleView导致滑动冲突或者显示不全的问题 2 解决办法 1).ScrollView替换成普通布局,然后RecycleView用的BaseMultiItem ...

  6. Android进阶知识:事件分发与滑动冲突(一)

    1.前言 Android学习一段时间,需求做多了必然会遇到滑动冲突问题,比如在一个ScrollView中要嵌套一个地图View,这时候触摸移动地图或者放大缩小地图就会变得不太准确甚至没有反应,这就是遇 ...

  7. Android滑动冲突解决方法

    Android滑动冲突解决方法 滑动冲突 首先讲解一下什么是滑动冲突.当你需要在一个ScrollView中嵌套使用ListView或者RecyclerView的时候你会发现只有ScrollView能够 ...

  8. Android开发之解决ListView和ScrollView滑动冲突的方法

    我们看下图: 不管怎么滑动都无法显示listview的剩余数据,只能显示一条,我们看下布局,ScrollView里面嵌套ListView <?xml version="1.0" ...

  9. Android之 如何解决ScrollView 和ListView滑动冲突的问题如何解决ScrollView can host only one direct child

    android 采用ScrollView布局时出现异常:ScrollView can host only one direct child. 解决办法:主要是ScrollView内部只能有一个子元素, ...

最新文章

  1. 在mysql中创建表的命令行_如何在命令行创建一个MySQL数据库
  2. 2021-01-26 Python自动化办公-处理word文档
  3. Java中怎样根据对象list的某对象的属性进行分组
  4. 关于Git的一些经验总结
  5. 并发编程——线程——理论知识
  6. Dialog Fragment DOM Area Design
  7. ASP.NET Core 查看应用状态和统计
  8. 【转】Dalvik虚拟机的启动过程分析
  9. 循环智能杨植麟:“人机耦合”将是对话语义应用的新趋势!
  10. Visio 中如何画实现接口的连线
  11. Android MediaPlayer 属性
  12. 使用Popup窗口创建无限级Web页菜单(4)
  13. logback.xml 配置总结
  14. 解决Mac无法睡眠问题
  15. 张江男曲折的出国梦_IT新闻_博客园
  16. 第六章 XML 拨号方案
  17. 伪造的指纹能鉴定出来吗_指纹鉴定能鉴定多久时间的指纹 一个月能鉴定出来吗 主要是一个包上有三四个人的指纹 可以鉴定出来吗...
  18. 阿里云服务器Intel Xeon Platinum 8269CY(Cascade Lake)处理器CPU性能评测
  19. 农业病虫害数据集与算法——调研整理
  20. JVM、JDK、JER介绍

热门文章

  1. ArcEngine数据编辑--选择要素
  2. mysql 重要维护工具 图解
  3. iOS开发 字符串的转化 小技巧
  4. unity中静态变量的使用
  5. SQLGrammarException错误
  6. python学习之老男孩python全栈第九期_day019知识点总结——collections模块、时间模块、random模块、os模块、sys模块...
  7. centos下安装JAVA开发工具(1)------JDK
  8. 如何激活windows的远程终端
  9. CCNA-3-Cisco静态路由
  10. 局域网内通过代理服务器上网的详细设置