返回

揭秘谷歌源码的陷阱:AppBarLayout的BUG启示录

Android

震惊!谷歌源码也有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。在开发过程中,我们应该时刻保持警惕,仔细排查问题,并找到解决方案。同时,我们也应该不断学习,提高自己的开发水平,以避免踩坑。

常见问题解答

  1. 为什么会出现AppBarLayout折叠效果失效的问题?
    答:因为AppBarLayout.Behavior无法注册嵌套滚动监听器。

  2. 如何修复AppBarLayout折叠效果失效的问题?
    答:重写NestedScrollView的onStartNestedScroll()方法,并在其中调用AppBarLayout.Behavior.startNestedScroll()方法。

  3. 什么是CoordinatorLayout?
    答:CoordinatorLayout是一个强大的布局容器,它允许我们轻松实现复杂的布局。

  4. 什么是Behavior?
    答:Behavior是CoordinatorLayout的一个重要概念,它定义了子视图在CoordinatorLayout中的行为方式。

  5. 什么是AppBarLayout?
    答:AppBarLayout是CoordinatorLayout中一个常见的子视图,它可以实现标题栏的折叠效果。