CoordinatorLayout使用中的坑
来源:互联网 发布:股票持仓软件 编辑:程序博客网 时间:2024/06/06 06:44
前言:因为项目中有个界面使用到父view和子view嵌套滑动的效果,所以想使用CoordinatorLayout来实现。在这当中遇到一些坑,本文作为一个记录。
现在用的UI库版本: compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.android.support:support-v4:24.2.1'
compile 'com.android.support:design:24.2.1'
ps:因为我现在遇到的坑可能在之后的版本会修复,所以就先版本写这。
页面大体结构:
刚开始的实现想法是,整个结构是CoordinatorLayout,包含一个AppbarLayout作为头部View,下面是一个ViewPager指示器,再下面是一个ViewPager。
最终效果:
主页布局代码:
<?xml version="1.0" encoding="utf-8"?><android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.oacg.collapsingtoolbarlayoutdemo.CoorAndViewPagerActivity"> <android.support.design.widget.AppBarLayout android:id="@+id/profile_app_bar_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" android:fitsSystemWindows="true"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/profile_collapsing_toolbar_layout" android:layout_width="match_parent" android:layout_height="280dp" app:layout_scrollFlags="scroll|exitUntilCollapsed" app:contentScrim="?attr/colorPrimary" android:fitsSystemWindows="true"> <ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="280dp" android:scaleType="centerCrop" android:fitsSystemWindows="true" android:src="@drawable/bg" android:maxHeight="192dp" app:layout_collapseMode="parallax"/> </android.support.design.widget.CollapsingToolbarLayout> <com.oacg.collapsingtoolbarlayoutdemo.SimpleViewPagerIndicator android:id="@+id/indicator" android:layout_width="match_parent" android:layout_height="50dp"/> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/viewpager" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:layout_width="match_parent" android:layout_height="match_parent"/></android.support.design.widget.CoordinatorLayout>
出现的问题:
在滚动的时候出现一种卡顿的现象。主要是在NestedScrollView向上滚动和RecyclerView向下滚动的时候。AppbarLayout的滚动非常的不流畅。感觉上是没有了惯性滑动。
解决办法:
1.
这里可以看到 为了头部View滚动优先于ViewPager,所以我在给CollapsingToolbarLayout设置app:layout_scrollFlags
的时候我使用的是:scroll|exitUntilCollapsed
。加入ViewPager中的NestedScrollView和RecyclerView比较短的时候,可以考虑使用 scroll|exitUntilCollapsed|enterAlways
。
- 会出现的问题:
1.加入”enterAlways”这个flags后ViewPager会和头部View一起滚动。这样会造成:向下滚动的时候,你的头部View早就已经完全展开了,但是你的RecyclerView还没有滚动到顶部。或者向上滚动的时候,你的头部View还没有完全的折叠,你的RecyclerView已经向上滚动隐藏了一部分了。
2.加上这个之后NestedScrollView的滚动更加卡顿了,不管是向上还是向下。当然可以使用RecyclerView来代替NestedScrollView。但是会增加部分代码,并且不直观。
2.
上面的解决方式显然是有很大的局限性。那么第二种解决方式。
即:
http://stackoverflow.com/questions/30923889/flinging-with-recyclerview-appbarlayout 第一个答案。用于解决RecyclerView的问题。
出现这种问题的原因大体上是因为RecyclerView在分发fling的时候出现了错误,导致AppbarLayout并没有获得fling的指令。所以这个方法,就自己重新计算了时候需要fling的判断。
但是这个方法还是没法解决NestedScrollView的滑动卡顿问题。虽然上面链接的第二个答案,看上去能解决NestedScrollView的滑动卡顿问题,但是并没有卵用。这个之后再说。
- 会出现的问题:这种方式上基本可满足大体的情况。但是还有个问题就是当一个快速滚动遇到,AppbarLayout显示或者隐藏的交界的时候会停止。也就说一个fling事件只能在ViewPager或者AppbarLayout其中一个View中起作用,不能够在他们之间传递。所以会出现但我们再怎么用力滑动ViewPager中的控件,滑动的惯性都不会把AppbarLayout带着滚动起来。但是在腾讯漫画的目录页就实现了这个效果,至于腾讯漫画怎么实现的下次再说。
效果图:
3.
上面的解决办法,大多是对于RecyclerView的对于NestedScrollView是无效的。因为在NestedScrollView根本就没有把fling正确的发出来。NestedScrollView的onTouchEvent()方法中:
case MotionEvent.ACTION_UP: if (mIsBeingDragged) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.addMovement(vtev); velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int initialVelocity = (int) VelocityTrackerCompat.getYVelocity(velocityTracker, mActivePointerId); if ((Math.abs(initialVelocity) > mMinimumVelocity)) { flingWithNestedDispatch(-initialVelocity); } else if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0, getScrollRange())) { ViewCompat.postInvalidateOnAnimation(this); } } mActivePointerId = INVALID_POINTER; endDrag(); break;
触发up事件的时候会来处理fling事件。flingWithNestedDispatch(-initialVelocity)
用来发送fling事件和处理fling事件。出现卡顿的时候就是if (mIsBeingDragged)
这个判断为false的时候。
那么解决NestedScrollView滚动卡顿的办法就是:自己新建一个类,然后将NestedScrollView中的代码copy到新的类中,并在onTouchEvent()方法的case MotionEvent.ACTION_UP:
中去掉if (mIsBeingDragged)
判断,然后就可以流畅的滑动了。至于这个判断去掉会不会有什么其他问题,暂时我还没发现,如果您知道请务必告诉我。谢谢。
总结:CoordinatorLayout上的这个卡顿的问题,官方早就知道这个问题,官方说是v23就修复的,
现在v24了也没有变化。可以看这里的讨论。https://code.google.com/p/android/issues/detail?id=179501
As I said in the talk, no there is ETA and may not even land. Closing comments until we do. 看到这句话一口老血吐出来。
所以在stackoverflow.com有很多的讨论,而且也有很多的解决办法,我感觉能达到的效果的都是有限的。不能真正的解决问题。
ps:https://github.com/henrytao-me/smooth-app-bar-layout 这个库是实现类似效果的,具体的效果怎么我没有去试。
pps: coordinatorlayout在android6.0的华为的机子上测试的时候快速滑动RecyclerView,会出现跳动的问题,暂时还不知道是因为我设置的问题还是因为coordinatorlayout的bug。
源码地址:https://github.com/BigggFish/CoordinatorlayoutDemo
参考:
http://dk-exp.com/2016/03/30/CoordinatorLayout/
http://stackoverflow.com/questions/30923889/flinging-with-recyclerview-appbarlayout
http://stackoverflow.com/questions/38119661/smooth-scroll-and-fling-with-nestedscrollview-appbarlayout-and-coordinatorlayout?rq=1
- CoordinatorLayout使用中的坑
- CoordinatorLayout与NestedScrollView嵌套RecyclerView使用中的坑
- CoordinatorLayout与NestedScrollView嵌套RecyclerView使用中的坑
- CoordinatorLayout与NestedScrollView嵌套RecyclerView使用中的坑
- Android 5.0中的CoordinatorLayout使用技巧
- 使用CoordinatorLayout
- CoordinatorLayout使用
- CoordinatorLayout使用
- CoordinatorLayout使用
- CoordinatorLayout使用
- 使用CoordinatorLayout
- 使用CoordinatorLayout
- coordinatorlayout使用
- 使用CoordinatorLayout
- 使用CoordinatorLayout
- CoordinatorLayout中的大坑
- android CoordinatorLayout使用
- CoordinatorLayout、SwipeRefreshLayout的使用
- 字符串反转,单词反转
- 在浏览器地址栏按回车、F5、Ctrl+F5刷新网页的区别
- QSlider和QLCDNumber 滑块 LCD
- JS实现网页全屏与退出全屏
- CSS content换行技术实现字符animation loading效果
- CoordinatorLayout使用中的坑
- 学习小记-MySQL
- 第三周的第一天,心情很down。
- Edittext判断输入是否为数字(包含小数点)
- iScroll上拉加载下拉刷新 -> 遇到的问题
- Javascript的this用法
- 传递userdata到lua
- linux常用命令
- java 判断字符串全为汉字 提取字符串中的汉字