Account for offset rounding errors during layout for DrawerLayout
In some cases a layout can occur that would alter the expected
movement patterns of DrawerLayout. Make sure that any movement from
rounding differences is accounted for and any state adjusted.
By updating lp.onScreen during the layout process to take the new real
position of the view into account, this state will be up to date when
computeScroll is called to update other associated drawer state used
later in touch interception, scrim drawing, drawer view visibility,
etc.
Bug 8918177
Change-Id: Ib65a86af448a433cd36bd0d5f49c6697c33a91f3
diff --git a/v4/java/android/support/v4/widget/DrawerLayout.java b/v4/java/android/support/v4/widget/DrawerLayout.java
index cc55b82..e5455b4 100644
--- a/v4/java/android/support/v4/widget/DrawerLayout.java
+++ b/v4/java/android/support/v4/widget/DrawerLayout.java
@@ -639,6 +639,7 @@
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mInLayout = true;
+ final int width = r - l;
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
@@ -658,12 +659,17 @@
final int childHeight = child.getMeasuredHeight();
int childLeft;
+ final float newOffset;
if (checkDrawerViewGravity(child, Gravity.LEFT)) {
childLeft = -childWidth + (int) (childWidth * lp.onScreen);
+ newOffset = (float) (childWidth + childLeft) / childWidth;
} else { // Right; onMeasure checked for us.
- childLeft = r - l - (int) (childWidth * lp.onScreen);
+ childLeft = width - (int) (childWidth * lp.onScreen);
+ newOffset = (float) (width - childLeft) / childWidth;
}
+ final boolean changeOffset = newOffset != lp.onScreen;
+
final int vgrav = lp.gravity & Gravity.VERTICAL_GRAVITY_MASK;
switch (vgrav) {
@@ -699,8 +705,13 @@
}
}
- if (lp.onScreen == 0) {
- child.setVisibility(INVISIBLE);
+ if (changeOffset) {
+ setDrawerViewOffset(child, newOffset);
+ }
+
+ final int newVisibility = lp.onScreen > 0 ? VISIBLE : INVISIBLE;
+ if (child.getVisibility() != newVisibility) {
+ child.setVisibility(newVisibility);
}
}
}