揭秘谷歌源码的陷阱:AppBarLayout的BUG启示录
2024-01-12 05:04:45
震惊!谷歌源码也有BUG?踩坑AppBarLayout,这一次要彻底搞懂CoordinatorLayout + Behavior!
在Android开发中,CoordinatorLayout是一个强大的布局容器,它允许我们轻松实现复杂的布局,比如滚动联动、浮动按钮等。AppBarLayout则是CoordinatorLayout中一个常见的子视图,它可以实现标题栏的折叠效果。
然而,在使用AppBarLayout时,我们可能会遇到一个奇怪的BUG:当AppBarLayout与NestedScrollView嵌套使用时,滑动NestedScrollView时,AppBarLayout的折叠效果会失效。这到底是怎么回事呢?
问题出在哪?
经过一番排查,我们发现问题出在AppBarLayout的Behavior上。Behavior是CoordinatorLayout的一个重要概念,它定义了子视图在CoordinatorLayout中的行为方式。AppBarLayout的Behavior是AppBarLayout.Behavior,它负责AppBarLayout的折叠效果。
为什么会出现失效问题呢?
在AppBarLayout.Behavior的onNestedPreScroll()方法中,有一行代码:
if (scrollingChild instanceof NestedScrollingChild2) {
return ((NestedScrollingChild2) scrollingChild).startNestedScroll(scrollingChild, this, ViewCompat.SCROLL_AXIS_VERTICAL);
}
这段代码的作用是,当AppBarLayout的父视图是NestedScrollingChild2时,调用NestedScrollingChild2.startNestedScroll()方法来注册嵌套滚动监听器。
然而,在我们的例子中,NestedScrollView并不是NestedScrollingChild2,因此不会调用NestedScrollingChild2.startNestedScroll()方法,导致AppBarLayout的Behavior无法注册嵌套滚动监听器,从而导致折叠效果失效。
如何修复问题?
要修复这个问题,我们可以重写NestedScrollView的onStartNestedScroll()方法,并在其中调用AppBarLayout.Behavior.startNestedScroll()方法:
@Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes, int type) {
boolean started = super.onStartNestedScroll(child, target, nestedScrollAxes, type);
if (started && (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0) {
AppBarLayout.Behavior behavior = ((AppBarLayout.LayoutParams) appBarLayout.getLayoutParams()).getBehavior();
if (behavior != null) {
behavior.startNestedScroll(appBarLayout, this, ViewCompat.SCROLL_AXIS_VERTICAL);
}
}
return started;
}
这样,就可以修复AppBarLayout折叠效果失效的问题了。
总结
通过这个例子,我们了解到,即使是谷歌官方的源码,也可能存在BUG。在开发过程中,我们应该时刻保持警惕,仔细排查问题,并找到解决方案。同时,我们也应该不断学习,提高自己的开发水平,以避免踩坑。
常见问题解答
-
为什么会出现AppBarLayout折叠效果失效的问题?
答:因为AppBarLayout.Behavior无法注册嵌套滚动监听器。 -
如何修复AppBarLayout折叠效果失效的问题?
答:重写NestedScrollView的onStartNestedScroll()方法,并在其中调用AppBarLayout.Behavior.startNestedScroll()方法。 -
什么是CoordinatorLayout?
答:CoordinatorLayout是一个强大的布局容器,它允许我们轻松实现复杂的布局。 -
什么是Behavior?
答:Behavior是CoordinatorLayout的一个重要概念,它定义了子视图在CoordinatorLayout中的行为方式。 -
什么是AppBarLayout?
答:AppBarLayout是CoordinatorLayout中一个常见的子视图,它可以实现标题栏的折叠效果。