AppBarLayout继承自 LinearLayout
。它的直接childView可以设置:scrollFlags
,常用方式是:
app:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed|enterAlwaysCollapsed"
scroll:当RecyclerView向上滚时,childView会跟着一起向上滚并实现隐藏
enterAlways:当RecyclerView向下滚时,childView会跟着一起向下滚并重新显示
snap:当childView还没有完全隐藏或显示时,会根据当前滚动的距离,自动选择是隐藏还是显示
exitUntilCollapsed:随之滚动完成折叠后就保留在界面上,不再移除屏幕
小坑就是:
当AppBarLayout有多个childView时,并且每个childView有不同的scrollFlags
(不同或者没有)时,从第0~不能滑动的childView为止的childView会随着滚动而隐藏显示。
如下图(实际上能滑动的只有A、B):
因为计算可滑动范围时,getTotalScrollRange在AppBarLayout.Behavior中调用
/**
* Returns the scroll range of all children.
*
* @return the scroll range in px
*/
public final int getTotalScrollRange() {
if (mTotalScrollRange != INVALID_SCROLL_RANGE) {
return mTotalScrollRange;
}
int range = 0;
for (int i = 0, z = getChildCount(); i < z; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int childHeight = child.getMeasuredHeight();
final int flags = lp.mScrollFlags;
if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) {
// We're set to scroll so add the child's height
range += childHeight + lp.topMargin + lp.bottomMargin;
if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) {
// For a collapsing scroll, we to take the collapsed height into account.
// We also break straight away since later views can't scroll beneath
// us
range -= ViewCompat.getMinimumHeight(child);
break;
}
} else {
// 当一个childView不能滑动之后,之后的childView都不能滑动
// As soon as a view doesn't have the scroll flag, we end the range calculation.
// This is because views below can not scroll under a fixed view.
break;
}
}
return mTotalScrollRange = Math.max(0, range - getTopInset());
}
网友评论