解决AppBarLayout在华为手机6.0系统快速滑动时抖动问题

前言:

最近有个需求要做类似UC、今日头条标题栏吸附悬停效果,相信大家会用CoordinatorLayout+AppBarLayout来实现,于是加入了项目中,效果是实现了,玩得很愉快,可是玩了一会发现一个原生的bug,问题描述如下:用手指轻轻滑动CoordinatorLayout部分(, 上滑, 快速抬起手指, 形成一个fling操作. 其实就是向上滑动一下.这时, 整个CoordinatorLayout部分会向上移动(fling), 在停止移动之前, 在下面的白色区域(也就是xml布局中的NestedScrollView)来一个反向的滑动(fling) , 这时整个页面就会开始或大或小的抖动, 问题非常明显,刚开始还以为是我操作问题,后来找了几个测试机,小米、华为、魅族、三星在6.0的华为手机上非常明显,7.0没有出现此问题.

1.屏幕录制效果如下:

img

2.解决问题的方法如下:

自定义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);
    }

3.在布局中的使用方法如下:

img

4.布局代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

<android.support.v7.widget.Toolbar

android:layout_width="match_parent"

android:layout_height="?attr/actionBarSize"

android:gravity="center"

app:layout_collapseMode="pin"

app:layout_scrollFlags="scroll|enterAlways"

app:title="我的"

app:titleTextColor="@color/cfd5031" />

<View

android:layout_width="match_parent"

android:layout_height="1px"

android:background="@color/ce7e7e7" />

<android.support.design.widget.CoordinatorLayout

android:layout_width="match_parent"

android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout

android:id="@+id/jianshu_appbar_layout"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="@color/cffffff"

app:layout_behavior="fule.com.appbarlayoutdemo.view.CustomBehavior"

android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"

app:elevation="0dp">

<android.support.design.widget.CollapsingToolbarLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

app:layout_scrollFlags="scroll|exitUntilCollapsed"

app:statusBarScrim="@android:color/transparent"

app:titleEnabled="false">

<LinearLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical">

<android.support.constraint.ConstraintLayout

android:id="@+id/cl_my_info"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_marginTop="20dp"

android:focusable="true"

android:focusableInTouchMode="true">

<de.hdodenhof.circleimageview.CircleImageView

android:id="@+id/iv_onlive_face"

android:layout_width="80dp"

android:layout_height="80dp"

android:layout_marginLeft="15dp"

android:src="@drawable/user_photo"

app:layout_constraintLeft_toLeftOf="parent" />

<ImageView

android:id="@+id/iv_onlive_sex"

android:layout_width="20dp"

android:layout_height="20dp"

app:layout_constraintBottom_toBottomOf="@id/iv_onlive_face"

app:layout_constraintRight_toRightOf="@id/iv_onlive_face" />

<TextView

android:id="@+id/tv_mine_name"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="15dp"

android:text="小美女"

android:textColor="@color/c2d2d2d"

android:textSize="18sp"

app:layout_constraintLeft_toRightOf="@id/iv_onlive_face" />

<TextView

android:id="@+id/tv_mine_account"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="15dp"

android:layout_marginTop="10dp"

android:text="乐创号:102352"

android:textColor="@color/c666666"

android:textSize="12sp"

app:layout_constraintLeft_toRightOf="@id/iv_onlive_face"

app:layout_constraintTop_toBottomOf="@id/tv_mine_name" />

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginRight="15dp"

android:text="编辑资料"

android:textColor="@color/c666666"

android:textSize="12sp"

app:layout_constraintBaseline_toBaselineOf="@id/tv_mine_account"

app:layout_constraintRight_toRightOf="parent" />

<LinearLayout

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="15dp"

android:gravity="center_vertical"

android:orientation="horizontal"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toRightOf="@id/iv_onlive_face">

<ImageView

android:id="@+id/iv_my_level"

android:layout_width="17dp"

android:layout_height="17dp"

tools:background="@color/colorAccent" />

<TextView

android:id="@+id/tv_my_level"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="5dp"

android:layout_marginRight="4dp"

android:text="新手"

android:textColor="@color/c666666"

android:textSize="12sp" />

<ImageView

android:id="@+id/iv_my_diamonds"

android:layout_width="15dp"

android:layout_height="11dp"

android:layout_margin="6dp"

android:src="@drawable/diamond_one" />

<ImageView

android:id="@+id/iv_my_dis_level"

android:layout_width="18dp"

android:layout_height="18dp"

android:layout_marginLeft="15dp"

android:background="@color/cfd5031" />

<TextView

android:id="@+id/tv_my_dis_level"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="5dp"

android:text="董事"

android:textColor="@color/c666666"

android:textSize="12sp" />

<ImageView

android:id="@+id/iv_my_pro_level"

android:layout_width="18dp"

android:layout_height="18dp"

android:layout_marginLeft="15dp"

android:background="@color/cfd5031" />

<TextView

android:id="@+id/tv_my_pro_level"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="5dp"

android:text="高级讲师"

android:textColor="@color/c666666"

android:textSize="12sp" />

</LinearLayout>

</android.support.constraint.ConstraintLayout>

<View

style="@style/linee7e7e7"

android:layout_marginTop="8dp" />

<LinearLayout

android:layout_width="match_parent"

android:layout_height="50dp"

android:layout_gravity="center"

android:orientation="horizontal"

app:layout_scrollFlags="scroll">

<TextView

android:id="@+id/item_label1"

android:layout_width="95dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@color/cffffff"

android:gravity="center"

android:text="小说精选"

android:textColor="@color/c2d2d2d"

android:textSize="14sp" />

<TextView

android:id="@+id/item_label2"

android:layout_width="95dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@color/cffffff"

android:gravity="center"

android:text="摄影游记"

android:textColor="@color/c2d2d2d"

android:textSize="14sp" />

<TextView

android:id="@+id/item_label3"

android:layout_width="95dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@color/cffffff"

android:gravity="center"

android:text="漫画手绘"

android:textColor="@color/c2d2d2d"

android:textSize="14sp" />

<TextView

android:id="@+id/item_label4"

android:layout_width="95dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@color/cffffff"

android:gravity="center"

android:text="签约作者"

android:textColor="@color/c2d2d2d"

android:textSize="14sp" />

</LinearLayout>

<View

style="@style/linee7e7e7"

android:layout_height="10dp" />

<LinearLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal">

<TextView

android:id="@+id/tv_my_follow"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:gravity="center"

android:padding="16dp"

android:text="关注 0"

android:textColor="@color/c2d2d2d"

android:textSize="16sp" />

<TextView

android:id="@+id/tv_my_fans"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:gravity="center"

android:padding="16dp"

android:text="粉丝 0"

android:textColor="@color/c2d2d2d"

android:textSize="16sp" />

<TextView

android:id="@+id/tv_my_home"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:gravity="center"

android:padding="16dp"

android:text="进入主页"

android:textColor="@color/c999999"

android:textSize="12sp" />

</LinearLayout>

<TextView

android:layout_width="match_parent"

android:layout_height="10dp"

android:background="@color/ce7e7e7"

android:visibility="visible" />

<LinearLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_marginTop="25dp">

<TextView

android:id="@+id/tv_my_account"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:drawablePadding="5dp"

android:drawableTop="@mipmap/account"

android:gravity="center"

android:text="@string/mine_account"

android:textColor="@color/c2d2d2d"

android:textSize="12sp" />

<TextView

android:id="@+id/tv_my_medal"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:drawablePadding="5dp"

android:drawableTop="@mipmap/medal"

android:gravity="center"

android:text="@string/mine_medal"

android:textColor="@color/c2d2d2d"

android:textSize="12sp" />

<TextView

android:id="@+id/tv_my_grade"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:drawablePadding="5dp"

android:drawableTop="@mipmap/grade"

android:gravity="center"

android:text="@string/mine_level"

android:textColor="@color/c2d2d2d"

android:textSize="12sp" />

<TextView

android:id="@+id/tv_my_growth"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:drawablePadding="5dp"

android:drawableTop="@mipmap/growth_value"

android:gravity="center"

android:text="@string/mine_growup"

android:textColor="@color/c2d2d2d"

android:textSize="12sp" />

<LinearLayout

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:gravity="center"

android:orientation="vertical">

<TextView

android:id="@+id/tv_my_identification"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_weight="1"

android:drawablePadding="5dp"

android:drawableTop="@mipmap/identification"

android:gravity="center"

android:text="@string/mine_authentication"

android:textColor="@color/c2d2d2d"

android:textSize="12sp" />

<TextView

android:id="@+id/tv_my_identification_des"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="未认证"

android:textColor="@color/c999999"

android:textSize="10sp" />

</LinearLayout>

</LinearLayout>

<LinearLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_marginBottom="20dp">

<TextView

android:id="@+id/tv_my_promotion"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:drawablePadding="5dp"

android:drawableTop="@mipmap/promotion"

android:gravity="center"

android:text="@string/mine_extension"

android:textColor="@color/c2d2d2d"

android:textSize="12sp" />

<LinearLayout

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:gravity="center"

android:orientation="vertical">

<TextView

android:id="@+id/tv_my_task"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_weight="1"

android:drawablePadding="5dp"

android:drawableTop="@mipmap/task_center"

android:gravity="center"

android:text="@string/mine_task"

android:textColor="@color/c2d2d2d"

android:textSize="12sp" />

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="未认证"

android:textColor="@color/c999999"

android:textSize="10sp" />

</LinearLayout>

<TextView

android:id="@+id/tv_my_visitor"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:drawablePadding="5dp"

android:drawableTop="@mipmap/visitor_management"

android:gravity="center"

android:text="@string/mine_visitor"

android:textColor="@color/c2d2d2d"

android:textSize="12sp" />

<TextView

android:id="@+id/tv_my_inter"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:drawablePadding="5dp"

android:drawableTop="@mipmap/points"

android:gravity="center"

android:text="@string/mine_inter"

android:textColor="@color/c2d2d2d"

android:textSize="12sp" />

<TextView

android:id="@+id/tv_my_help"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:drawablePadding="5dp"

android:drawableTop="@mipmap/help"

android:gravity="center"

android:text="@string/mine_help"

android:textColor="@color/c2d2d2d"

android:textSize="12sp" />

</LinearLayout>

</LinearLayout>

</android.support.design.widget.CollapsingToolbarLayout>

<View

android:layout_width="match_parent"

android:layout_height="1px"

android:background="@color/ce7e7e7" />

<LinearLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal">

<LinearLayout

android:id="@+id/ll_my_online"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:gravity="center"

android:orientation="vertical">

<TextView

android:id="@+id/tv_my_online"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="10dp"

android:text="@string/my_online"

android:textColor="@color/cfd5031"

android:textSize="14sp" />

<TextView

android:id="@+id/tv_my_online_mark"

android:layout_width="18dp"

android:layout_height="3dp"

android:layout_marginTop="9dp"

android:background="@color/cfd5031" />

</LinearLayout>

<LinearLayout

android:id="@+id/ll_my_video"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:gravity="center"

android:orientation="vertical">

<TextView

android:id="@+id/tv_my_video"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="10dp"

android:text="@string/my_video"

android:textColor="@color/c2d2d2d"

android:textSize="14sp" />

<TextView

android:id="@+id/tv_my_video_mark"

android:layout_width="18dp"

android:layout_height="3dp"

android:layout_marginTop="9dp"

android:background="@color/cfd5031"

android:visibility="invisible" />

</LinearLayout>

<LinearLayout

android:id="@+id/ll_my_collection"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:gravity="center"

android:orientation="vertical">

<TextView

android:id="@+id/tv_my_collection"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="10dp"

android:text="@string/my_collection"

android:textColor="@color/c2d2d2d"

android:textSize="14sp" />

<TextView

android:id="@+id/tv_my_collection_mark"

android:layout_width="18dp"

android:layout_height="3dp"

android:layout_marginTop="9dp"

android:background="@color/cfd5031"

android:visibility="invisible" />

</LinearLayout>

<LinearLayout

android:id="@+id/ll_my_tracks"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:gravity="center"

android:orientation="vertical">

<TextView

android:id="@+id/tv_my_tracks"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="10dp"

android:text="@string/my_tracks"

android:textColor="@color/c2d2d2d"

android:textSize="14sp" />

<TextView

android:id="@+id/tv_my_tracks_mark"

android:layout_width="18dp"

android:layout_height="3dp"

android:layout_marginTop="9dp"

android:background="@color/cfd5031"

android:visibility="invisible" />

</LinearLayout>

</LinearLayout>

<TextView style="@style/linee7e7e7" />

</android.support.design.widget.AppBarLayout>

<android.support.v4.widget.NestedScrollView

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@color/white"

android:scrollbars="none"

app:layout_behavior="@string/appbar_scrolling_view_behavior">

<LinearLayout

android:id="@+id/ll_my_content"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

app:layout_scrollFlags="scroll|enterAlways">

</LinearLayout>

</android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

</LinearLayout>

5.大家可以亲自体验下没有加自定义的Behavior会出现啥问题,最后放上完整代码地址

AppBarLayoutDemo: 解决AppBarLayout在华为手机6.0上抖动的问题

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值