diff options
author | Chris Banes <chrisbanes@google.com> | 2016-06-09 09:36:09 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2016-06-09 09:36:09 +0000 |
commit | 1082886555fd037f1c8bf53b4f73483f202a3f4e (patch) | |
tree | 221d97a3eaf00c7aa4b4a29e4b640fe276a8cc1f | |
parent | 8d0bc8f74dd470a8a9c4ec8d28139396fb5266ab (diff) | |
parent | 2e522d2998c937948757ccfe0a5523047726fb4d (diff) | |
download | support-1082886555fd037f1c8bf53b4f73483f202a3f4e.tar.gz |
Merge "Fix scrolling view position with fitSystemWindows parent" into nyc-dev
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(); + } + }; + } } |