Make sure that AppBarLayout is laid out correctly
Currently, the scrolling view of a AppBarLayout relies
on CoLs pre draw listener to move itself. This is
problematic for things like activity transitions which
rely on correct position after a layout.
BUG: 23307267
Change-Id: Ibf508908cd22ef29d2c3752b299b8ce5d6346b0a
diff --git a/design/api/current.txt b/design/api/current.txt
index 789c239..30da82a 100644
--- a/design/api/current.txt
+++ b/design/api/current.txt
@@ -61,6 +61,7 @@
method public int getOverlayTop();
method public boolean layoutDependsOn(android.support.design.widget.CoordinatorLayout, android.view.View, android.view.View);
method public boolean onDependentViewChanged(android.support.design.widget.CoordinatorLayout, android.view.View, android.view.View);
+ method public boolean onLayoutChild(android.support.design.widget.CoordinatorLayout, android.view.View, int);
method public boolean onMeasureChild(android.support.design.widget.CoordinatorLayout, android.view.View, int, int, int, int);
method public void setOverlayTop(int);
}
diff --git a/design/src/android/support/design/widget/AppBarLayout.java b/design/src/android/support/design/widget/AppBarLayout.java
index 9947b23..7c6e728 100644
--- a/design/src/android/support/design/widget/AppBarLayout.java
+++ b/design/src/android/support/design/widget/AppBarLayout.java
@@ -1269,8 +1269,30 @@
}
@Override
+ public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
+ // First lay out the child as normal
+ super.onLayoutChild(parent, child, layoutDirection);
+
+ // Now offset us correctly to be in the correct position. This is important for things
+ // like activity transitions which rely on accurate positioning after the first layout.
+ final List<View> dependencies = parent.getDependencies(child);
+ for (int i = 0, z = dependencies.size(); i < z; i++) {
+ if (updateOffset(parent, child, dependencies.get(i))) {
+ // If we updated the offset, break out of the loop now
+ break;
+ }
+ }
+ return true;
+ }
+
+ @Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child,
View dependency) {
+ updateOffset(parent, child, dependency);
+ return false;
+ }
+
+ private boolean updateOffset(CoordinatorLayout parent, View child, View dependency) {
final CoordinatorLayout.Behavior behavior =
((CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior();
if (behavior instanceof Behavior) {
@@ -1278,6 +1300,7 @@
final int offset = ((Behavior) behavior).getTopBottomOffsetForScrollingSibling();
setTopAndBottomOffset(dependency.getHeight() + offset
- getOverlapForOffset(dependency, offset));
+ return true;
}
return false;
}