AppBarLayout卡顿问题
项目中比较复杂的一个界面
CoordinatorLayout+AppBarLayout+CollapsingToolbarLayout+NestedScrollView+ViewPager+XRecyclerView
遇到的问题
- 快速上滑之后会短时间无法下滑,卡顿,ViewPager中的recyclerView加载更多有2秒左右的延迟,support包用的是26.1.0
- AppBarLayout顶部笔记高,顶部无法滑动,只能通过底部的ViewPager向上滑动
问题1,卡顿问题,查找了很多资料,包括Stack Overflow的一些高票答案都没有解决问题,这篇文章才是彻底解决了第一个问题https://blog.csdn.net/qq_17766199/article/details/82561216 ,这是android support的bug,28.0.0版本已经修复了
如果要在26版本使用
import android.content.Context;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;
/**
* 修复appbarlayout 滑动卡顿
* https://blog.csdn.net/qq_17766199/article/details/82561216
* RecyclerView 在 fling 过程中并没有通知AppBarLayout,所以在fling结束之后,AppBarLayout不知道当前RecyclerView的滑动到的位置,所以导致了这个滑动被打断的问题。其实相关的滑动卡顿问题,病因都是这里。
* support28已经修复了这个问题,但是项目现在用的26
* Created by ychen on 2019/4/20.
*/
public class FixAppBarLayoutBehavior extends AppBarLayout.Behavior {
public FixAppBarLayoutBehavior() {
super();
}
public FixAppBarLayoutBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@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);
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target,
int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
stopNestedScrollIfNeeded(dyUnconsumed, 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);
}
}
}
}
问题2,顶部无法滑动,解决方案https://blog.csdn.net/weixin_34150830/article/details/87316902#commentBox
//修复appBarlayout顶部高度过高无法滑动
mAppbar.post(() -> {
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) mAppbar.getLayoutParams();
AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) layoutParams.getBehavior();
behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
@Override
public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
return true;
}
});
});