最近有个需求要做类似 UC, 今日头条标题栏吸附悬停效果, 相信大家会用 CoordinatorLayout+AppBarLayout 来实现, 于是加入了项目中, 效果是实现了, 玩得很愉快, 可是玩了一会发现一个原生的 bug, 问题描述如下:
用手指轻轻滑动 CoordinatorLayout 部分 (, 上滑, 快速抬起手指, 形成一个 fling 操作. 其实就是向上滑动一下. 这时, 整个 CoordinatorLayout 部分会向上移动(fling), 在停止移动之前, 在下面的白色区域(也就是 xml 布局中的 NestedScrollView) 来一个反向的滑动(fling) , 这时整个页面就会开始或大或小的抖动, 非常明显.
屏幕录制如下:
标题
解决问题的方法如下:
自定义 AppBarLayout 的 Behavior 代码:
- /**
- * 自定义 AppBarLayout 的 Behavior 解决华为手机 6.0 系统抖动问题
- */
- public class CustomBehavior extends AppBarLayout.Behavior {
- private OverScroller mScroller;
- public CustomBehavior() {
- }
- public CustomBehavior(Context context, AttributeSet attrs) {
- super(context, attrs);
- getParentScroller(context);
- }
- /**
- * 反射获得滑动属性.
- *
- * @param context
- */
- private void getParentScroller(Context context) {
- if (mScroller != null) return;
- mScroller = new OverScroller(context);
- try {
- Class reflex_class = getClass().getSuperclass().getSuperclass();// 父类 AppBarLayout.Behavior 父类的父类 HeaderBehavior
- Field fieldScroller = reflex_class.getDeclaredField("mScroller");
- fieldScroller.setAccessible(true);
- fieldScroller.set(this, mScroller);
- } catch (Exception e) {
- }
- }
- //fling 上滑 appbar 然后迅速 fling 下滑 recycler 时, HeaderBehavior 的 mScroller 并未停止, 会导致上下来回晃动
- @Override
- public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int type) {
- if (mScroller != null) { // 当 recyclerView 做好滑动准备的时候 直接干掉 Appbar 的滑动
- if (mScroller.computeScrollOffset()) {
- mScroller.abortAnimation();
- }
- }
- if (type == ViewCompat.TYPE_NON_TOUCH && getTopAndBottomOffset() == 0) { //recyclerview 的惯性比较大 , 会顶在头部一会儿, 到头直接干掉它的滑动
- ViewCompat.stopNestedScroll(target, type);
- }
- super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
- }
- @Override
- public boolean onTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent e) {
- switch (e.getActionMasked()) {
- case MotionEvent.ACTION_DOWN:
- break;
- }
- return super.onTouchEvent(parent, child, e);
- }
在布局中的使用方法如下:
大家可以亲自体验下没有加自定义的 Behavior 会出现啥问题, 最后放上完整代码地址
https://gitee.com/jackning_admin/AppBarLayoutDemo
来源: https://www.2cto.com/kf/201808/775309.html