From 5cebd3208774e532b2db87890a76ab2faf8f1b6b Mon Sep 17 00:00:00 2001 From: TreeHugger Robot Date: Fri, 9 Dec 2016 02:42:44 +0000 Subject: [PATCH] Merge "Fix FAB showing as pressed when the user drags off it" into nyc-support-25.1-dev GitOrigin-RevId=099115399b63ce5e24da28017a2266379bd26930 PiperOrigin-RevId: 141511120 --- .../design/widget/FloatingActionButton.java | 11 +++-- .../design/testutils/TestUtilsActions.java | 23 +++++++++ .../design/testutils/TestUtilsMatchers.java | 17 +++++++ .../widget/FloatingActionButtonTest.java | 48 +++++++++++++++++++ 4 files changed, 96 insertions(+), 3 deletions(-) diff --git a/lib/src/android/support/design/widget/FloatingActionButton.java b/lib/src/android/support/design/widget/FloatingActionButton.java index 592ccef46..1597386b2 100644 --- a/lib/src/android/support/design/widget/FloatingActionButton.java +++ b/lib/src/android/support/design/widget/FloatingActionButton.java @@ -530,10 +530,15 @@ public class FloatingActionButton extends VisibilityAwareImageButton { @Override public boolean onTouchEvent(MotionEvent ev) { - if(getContentRect(mTouchArea) && !mTouchArea.contains((int) ev.getX(), (int) ev.getY())) { - return false; + switch (ev.getAction()) { + case MotionEvent.ACTION_DOWN: + // Skipping the gesture if it doesn't start in in the FAB 'content' area + if (getContentRect(mTouchArea) + && !mTouchArea.contains((int) ev.getX(), (int) ev.getY())) { + return false; + } + break; } - return super.onTouchEvent(ev); } diff --git a/lib/tests/src/android/support/design/testutils/TestUtilsActions.java b/lib/tests/src/android/support/design/testutils/TestUtilsActions.java index 4fc982d3e..528c41639 100644 --- a/lib/tests/src/android/support/design/testutils/TestUtilsActions.java +++ b/lib/tests/src/android/support/design/testutils/TestUtilsActions.java @@ -240,6 +240,29 @@ public class TestUtilsActions { }; } + public static ViewAction setClickable(final boolean clickable) { + return new ViewAction() { + @Override + public Matcher getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return "set clickable"; + } + + @Override + public void perform(UiController uiController, View view) { + uiController.loopMainThreadUntilIdle(); + + view.setClickable(clickable); + + uiController.loopMainThreadUntilIdle(); + } + }; + } + /** * Sets compound drawables on {@link TextView} */ diff --git a/lib/tests/src/android/support/design/testutils/TestUtilsMatchers.java b/lib/tests/src/android/support/design/testutils/TestUtilsMatchers.java index 2d95aa0cf..dc91ae94f 100644 --- a/lib/tests/src/android/support/design/testutils/TestUtilsMatchers.java +++ b/lib/tests/src/android/support/design/testutils/TestUtilsMatchers.java @@ -440,4 +440,21 @@ public class TestUtilsMatchers { } }; } + + /** + * Returns a matcher that matches {@link View}s that are pressed. + */ + public static Matcher isPressed() { + return new TypeSafeMatcher() { + @Override + public void describeTo(Description description) { + description.appendText("is pressed"); + } + + @Override + public boolean matchesSafely(View view) { + return view.isPressed(); + } + }; + } } diff --git a/lib/tests/src/android/support/design/widget/FloatingActionButtonTest.java b/lib/tests/src/android/support/design/widget/FloatingActionButtonTest.java index 248b9df36..5e5adcfcd 100644 --- a/lib/tests/src/android/support/design/widget/FloatingActionButtonTest.java +++ b/lib/tests/src/android/support/design/widget/FloatingActionButtonTest.java @@ -23,7 +23,9 @@ import static android.support.design.testutils.FloatingActionButtonActions.setIm import static android.support.design.testutils.FloatingActionButtonActions.setLayoutGravity; import static android.support.design.testutils.FloatingActionButtonActions.setSize; import static android.support.design.testutils.FloatingActionButtonActions.showThenHide; +import static android.support.design.testutils.TestUtilsActions.setClickable; import static android.support.design.testutils.TestUtilsActions.setEnabled; +import static android.support.design.testutils.TestUtilsMatchers.isPressed; import static android.support.design.testutils.TestUtilsMatchers.withFabBackgroundFill; import static android.support.design.testutils.TestUtilsMatchers.withFabContentAreaOnMargins; import static android.support.design.testutils.TestUtilsMatchers.withFabContentHeight; @@ -36,8 +38,13 @@ import static android.support.test.espresso.matcher.ViewMatchers.withId; import static org.hamcrest.Matchers.not; import android.graphics.Color; +import android.graphics.Rect; import android.support.design.test.R; import android.support.design.testutils.TestUtils; +import android.support.test.espresso.action.CoordinatesProvider; +import android.support.test.espresso.action.GeneralSwipeAction; +import android.support.test.espresso.action.Press; +import android.support.test.espresso.action.Swipe; import android.support.test.filters.SmallTest; import android.view.Gravity; import android.view.View; @@ -139,6 +146,47 @@ public class FloatingActionButtonTest .check(matches(not(isDisplayed()))); } + @Test + public void testClickableTouchAndDragOffView() { + onView(withId(R.id.fab_standard)) + .perform(setClickable(true)) + .perform(new GeneralSwipeAction( + Swipe.SLOW, + new CoordinatesProvider() { + @Override + public float[] calculateCoordinates(View view) { + // Create coordinators that in the center of the FAB's content area + final FloatingActionButton fab = (FloatingActionButton) view; + + final int[] xy = new int[2]; + fab.getLocationOnScreen(xy); + final Rect rect = new Rect(); + fab.getContentRect(rect); + + return new float[] { + xy[0] + rect.centerX(), + xy[1] + rect.centerY() + }; + } + }, + new CoordinatesProvider() { + @Override + public float[] calculateCoordinates(View view) { + // Create coordinators that in the center horizontally, but well + // below the view vertically (by 50% of the height) + final int[] xy = new int[2]; + view.getLocationOnScreen(xy); + + return new float[]{ + xy[0] + (view.getWidth() / 2f), + xy[1] + (view.getHeight() * 1.5f) + }; + } + }, + Press.FINGER)) + .check(matches(not(isPressed()))); + } + @Test public void testSetCompatElevation() { onView(withId(R.id.fab_standard))