FixAppBarLayoutBehavior的小小改进

关于CoordinatorLayout和AppBarLayout 嵌套滑动时抖动的一个原生bug网上有很多文章,我就不细说了,可以看一下这个CoordinatorLayout和AppBarLayout 嵌套滑动时抖动的一个原生bug,里面涉及到的FixAppBarLayoutBehavior这个类,关于反射拿到OverScroller对象实体的地方,需要小小改进一下,如下,此处就做一个小小的记录吧。

package com.msyc.onion.ui.commons.behavior;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.OverScroller;

import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.view.ViewCompat;

import com.google.android.material.appbar.AppBarLayout;

import java.lang.reflect.Field;

import static android.view.MotionEvent.ACTION_DOWN;

/**
 * Workaround AppBarLayout.Behavior for https://issuetracker.google.com/66996774
 * 

* See https://gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2 for * example usage. *

* Change the package name as you wish. */ public class FixAppBarLayoutBehavior extends AppBarLayout.Behavior { private static final String TAG = "AppBarLayoutBehavior"; public FixAppBarLayoutBehavior() { super(); } public FixAppBarLayoutBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev) { if (ev.getAction() == ACTION_DOWN) { Object scroller = getSuperSuperField(this); if (scroller != null && scroller instanceof OverScroller) { OverScroller overScroller = (OverScroller) scroller; overScroller.abortAnimation(); } } return super.onInterceptTouchEvent(parent, child, ev); } private Object getSuperSuperField(Object paramClass) { Field field; Object object = null; try { Class cla = (Class) paramClass.getClass().getSuperclass().getSuperclass().getSuperclass(); field = cla.getDeclaredField("scroller"); field.setAccessible(true); System.out.println("单个对象的某个键的值==反射==" + field.get(paramClass)); object = field.get(paramClass); if (object == null) { field = paramClass.getClass().getSuperclass().getSuperclass().getDeclaredField("mScroller"); field.setAccessible(true); object = field.get(paramClass); } } catch (Exception e) { e.printStackTrace(); } return object; } @Override public void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type, int[] consume) { super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type, consume); stopNestedScrollIfNeeded(dyUnconsumed, child, target, type); } @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int type) { super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type); stopNestedScrollIfNeeded(dy, child, target, type); } private void stopNestedScrollIfNeeded(int dy, AppBarLayout child, View target, int type) { if (type == ViewCompat.TYPE_NON_TOUCH) { final int currOffset = getTopAndBottomOffset(); if ((dy < 0 && currOffset == 0) || (dy > 0 && currOffset == -child.getTotalScrollRange())) { ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH); } } } }

你可能感兴趣的:(FixAppBarLayoutBehavior的小小改进)