aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Banes <chrisbanes@google.com>2016-06-09 09:36:09 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2016-06-09 09:36:09 +0000
commit1082886555fd037f1c8bf53b4f73483f202a3f4e (patch)
tree221d97a3eaf00c7aa4b4a29e4b640fe276a8cc1f
parent8d0bc8f74dd470a8a9c4ec8d28139396fb5266ab (diff)
parent2e522d2998c937948757ccfe0a5523047726fb4d (diff)
downloadsupport-1082886555fd037f1c8bf53b4f73483f202a3f4e.tar.gz
Merge "Fix scrolling view position with fitSystemWindows parent" into nyc-dev
-rw-r--r--design/src/android/support/design/widget/CoordinatorLayout.java4
-rw-r--r--design/src/android/support/design/widget/HeaderScrollingViewBehavior.java11
-rw-r--r--design/tests/res/layout/include_appbar_scrollview.xml1
-rw-r--r--design/tests/src/android/support/design/widget/AppBarWithToolbarTest.java56
-rwxr-xr-xdesign/tests/src/android/support/design/widget/BaseDynamicCoordinatorLayoutTest.java25
5 files changed, 97 insertions, 0 deletions
diff --git a/design/src/android/support/design/widget/CoordinatorLayout.java b/design/src/android/support/design/widget/CoordinatorLayout.java
index 94e908a3762..b86a9777159 100644
--- a/design/src/android/support/design/widget/CoordinatorLayout.java
+++ b/design/src/android/support/design/widget/CoordinatorLayout.java
@@ -344,6 +344,10 @@ public class CoordinatorLayout extends ViewGroup implements NestedScrollingParen
return insets;
}
+ final WindowInsetsCompat getLastWindowInsets() {
+ return mLastInsets;
+ }
+
/**
* Reset all Behavior-related tracking records either to clean up or in preparation
* for a new event stream. This should be called when attached or detached from a window,
diff --git a/design/src/android/support/design/widget/HeaderScrollingViewBehavior.java b/design/src/android/support/design/widget/HeaderScrollingViewBehavior.java
index 129521a16e1..4d98986927c 100644
--- a/design/src/android/support/design/widget/HeaderScrollingViewBehavior.java
+++ b/design/src/android/support/design/widget/HeaderScrollingViewBehavior.java
@@ -21,6 +21,7 @@ import android.graphics.Rect;
import android.support.design.widget.CoordinatorLayout.Behavior;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.ViewCompat;
+import android.support.v4.view.WindowInsetsCompat;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
@@ -111,6 +112,16 @@ abstract class HeaderScrollingViewBehavior extends ViewOffsetBehavior<View> {
parent.getHeight() + header.getBottom()
- parent.getPaddingBottom() - lp.bottomMargin);
+ final WindowInsetsCompat parentInsets = parent.getLastWindowInsets();
+ if (parentInsets != null && ViewCompat.getFitsSystemWindows(parent)
+ && !ViewCompat.getFitsSystemWindows(child)) {
+ // If we're set to handle insets but this child isn't, then it has been measured as
+ // if there are no insets. We need to lay it out to match horizontally.
+ // Top and bottom and already handled in the logic above
+ available.left += parentInsets.getSystemWindowInsetLeft();
+ available.right -= parentInsets.getSystemWindowInsetRight();
+ }
+
final Rect out = mTempRect2;
GravityCompat.apply(resolveGravity(lp.gravity), child.getMeasuredWidth(),
child.getMeasuredHeight(), available, out, layoutDirection);
diff --git a/design/tests/res/layout/include_appbar_scrollview.xml b/design/tests/res/layout/include_appbar_scrollview.xml
index 22a72767ebc..529a38b0d81 100644
--- a/design/tests/res/layout/include_appbar_scrollview.xml
+++ b/design/tests/res/layout/include_appbar_scrollview.xml
@@ -17,6 +17,7 @@
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/scrolling_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
diff --git a/design/tests/src/android/support/design/widget/AppBarWithToolbarTest.java b/design/tests/src/android/support/design/widget/AppBarWithToolbarTest.java
index 22bf268a2c7..5fc25f620af 100644
--- a/design/tests/src/android/support/design/widget/AppBarWithToolbarTest.java
+++ b/design/tests/src/android/support/design/widget/AppBarWithToolbarTest.java
@@ -16,10 +16,15 @@
package android.support.design.widget;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+
import static org.junit.Assert.assertEquals;
import android.support.design.test.R;
+import android.support.v4.view.ViewCompat;
import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
import org.junit.Test;
@@ -70,4 +75,55 @@ public class AppBarWithToolbarTest extends AppBarLayoutBaseTest {
assertEquals(originalAppbarBottom, appbarOnScreenXY[1] + appbarHeight, 1);
}
+ /**
+ * Tests a AppBarLayout + scrolling content with fitSystemWindows = undefined,
+ * with a fitSystemWindows = true parent
+ */
+ @Test
+ public void testScrollingContentPositionWithFitSystemWindowsParent() {
+ configureContent(R.layout.design_appbar_toolbar_scroll_fitsystemwindows_parent,
+ R.string.design_appbar_toolbar_scroll_tabs_pin);
+
+ final int[] appbarOnScreenXY = new int[2];
+ mAppBar.getLocationOnScreen(appbarOnScreenXY);
+
+ final View scrollingContent = mCoordinatorLayout.findViewById(R.id.scrolling_content);
+ final int[] scrollingContentOnScreenXY = new int[2];
+ scrollingContent.getLocationOnScreen(scrollingContentOnScreenXY);
+
+ // Assert that they have the same left
+ assertEquals(appbarOnScreenXY[0], scrollingContentOnScreenXY[0]);
+ // ...and the same width
+ assertEquals(mAppBar.getWidth(), scrollingContent.getWidth());
+ // ...and are vertically stacked
+ assertEquals(mAppBar.getBottom(), scrollingContent.getTop());
+ }
+
+ /**
+ * Tests a AppBarLayout + scrolling content with fitSystemWindows = undefined,
+ * with a fitSystemWindows = true parent, in RTL
+ */
+ @Test
+ public void testScrollingContentPositionWithFitSystemWindowsParentInRtl() {
+ configureContent(R.layout.design_appbar_toolbar_scroll_fitsystemwindows_parent,
+ R.string.design_appbar_toolbar_scroll_tabs_pin);
+
+ // Force RTL
+ onView(withId(R.id.app_bar)).perform(setLayoutDirection(ViewCompat.LAYOUT_DIRECTION_RTL));
+
+ final int[] appbarOnScreenXY = new int[2];
+ mAppBar.getLocationOnScreen(appbarOnScreenXY);
+
+ final View scrollingContent = mCoordinatorLayout.findViewById(R.id.scrolling_content);
+ final int[] scrollingContentOnScreenXY = new int[2];
+ scrollingContent.getLocationOnScreen(scrollingContentOnScreenXY);
+
+ // Assert that they have the same left
+ assertEquals(appbarOnScreenXY[0], scrollingContentOnScreenXY[0]);
+ // ...and the same width
+ assertEquals(mAppBar.getWidth(), scrollingContent.getWidth());
+ // ...and are vertically stacked
+ assertEquals(mAppBar.getBottom(), scrollingContent.getTop());
+ }
+
}
diff --git a/design/tests/src/android/support/design/widget/BaseDynamicCoordinatorLayoutTest.java b/design/tests/src/android/support/design/widget/BaseDynamicCoordinatorLayoutTest.java
index 9239940509c..8c6f331dcdf 100755
--- a/design/tests/src/android/support/design/widget/BaseDynamicCoordinatorLayoutTest.java
+++ b/design/tests/src/android/support/design/widget/BaseDynamicCoordinatorLayoutTest.java
@@ -20,6 +20,7 @@ import android.support.design.test.R;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
+import android.support.v4.view.ViewCompat;
import android.view.View;
import android.view.ViewStub;
import org.hamcrest.Description;
@@ -29,6 +30,7 @@ import org.junit.After;
import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.any;
/**
* Base class for tests that are exercising various aspects of {@link CoordinatorLayout}.
@@ -102,4 +104,27 @@ public abstract class BaseDynamicCoordinatorLayoutTest
}
};
}
+
+ protected ViewAction setLayoutDirection(final int layoutDir) {
+ return new ViewAction() {
+ @Override
+ public Matcher<View> getConstraints() {
+ return any(View.class);
+ }
+
+ @Override
+ public String getDescription() {
+ return "Sets layout direction";
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ uiController.loopMainThreadUntilIdle();
+
+ ViewCompat.setLayoutDirection(view, layoutDir);
+
+ uiController.loopMainThreadUntilIdle();
+ }
+ };
+ }
}