diff options
author | 2019-01-30 15:44:42 -0800 | |
---|---|---|
committer | 2019-01-30 15:47:42 -0800 | |
commit | de5b5850726e3cd24651be85ffd2072565be7532 (patch) | |
tree | aa73bc6bf9518db7d45244a9585e6cf526ec2538 | |
parent | 5e5aebe9f602cbbb6403ae3e6a8cefd48872dd8c (diff) |
Allow ActionBarShadowController to attach to Views.
Instead of only allowing ActionbarShadowController to attach to
RecyclerViews, we allow it to attach to any View, as we can listen to
scroll events on them.
Test: See correct behavior when scrolling app info.
Test: atest ActionBarShadowControllerTest
Change-Id: I286a83599bd60ca0a592ee49198b284c5561ec58
2 files changed, 43 insertions, 36 deletions
diff --git a/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java b/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java index 68ba5fbd120f..be3365fcc5ff 100644 --- a/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java +++ b/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java @@ -27,7 +27,6 @@ import androidx.annotation.VisibleForTesting; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.OnLifecycleEvent; -import androidx.recyclerview.widget.RecyclerView; /** * UI controller that adds a shadow appear/disappear animation to action bar scroll. @@ -41,40 +40,36 @@ public class ActionBarShadowController implements LifecycleObserver { @VisibleForTesting ScrollChangeWatcher mScrollChangeWatcher; - private RecyclerView mRecyclerView; + private View mScrollView; private boolean mIsScrollWatcherAttached; /** * Wire up the animation to to an {@link Activity}. Shadow will be applied to activity's * action bar. */ - public static ActionBarShadowController attachToRecyclerView( - Activity activity, Lifecycle lifecycle, RecyclerView recyclerView) { - return new ActionBarShadowController(activity, lifecycle, recyclerView); + public static ActionBarShadowController attachToView( + Activity activity, Lifecycle lifecycle, View scrollView) { + return new ActionBarShadowController(activity, lifecycle, scrollView); } /** * Wire up the animation to to a {@link View}. Shadow will be applied to the view. */ - public static ActionBarShadowController attachToRecyclerView( - View anchorView, Lifecycle lifecycle, RecyclerView recyclerView) { - return new ActionBarShadowController(anchorView, lifecycle, recyclerView); + public static ActionBarShadowController attachToView( + View anchorView, Lifecycle lifecycle, View scrollView) { + return new ActionBarShadowController(anchorView, lifecycle, scrollView); } - private ActionBarShadowController(Activity activity, Lifecycle lifecycle, - RecyclerView recyclerView) { - mScrollChangeWatcher = - new ActionBarShadowController.ScrollChangeWatcher(activity); - mRecyclerView = recyclerView; + private ActionBarShadowController(Activity activity, Lifecycle lifecycle, View scrollView) { + mScrollChangeWatcher = new ActionBarShadowController.ScrollChangeWatcher(activity); + mScrollView = scrollView; attachScrollWatcher(); lifecycle.addObserver(this); } - private ActionBarShadowController(View anchorView, Lifecycle lifecycle, - RecyclerView recyclerView) { - mScrollChangeWatcher = - new ActionBarShadowController.ScrollChangeWatcher(anchorView); - mRecyclerView = recyclerView; + private ActionBarShadowController(View anchorView, Lifecycle lifecycle, View scrollView) { + mScrollChangeWatcher = new ActionBarShadowController.ScrollChangeWatcher(anchorView); + mScrollView = scrollView; attachScrollWatcher(); lifecycle.addObserver(this); } @@ -83,21 +78,21 @@ public class ActionBarShadowController implements LifecycleObserver { private void attachScrollWatcher() { if (!mIsScrollWatcherAttached) { mIsScrollWatcherAttached = true; - mRecyclerView.addOnScrollListener(mScrollChangeWatcher); - mScrollChangeWatcher.updateDropShadow(mRecyclerView); + mScrollView.setOnScrollChangeListener(mScrollChangeWatcher); + mScrollChangeWatcher.updateDropShadow(mScrollView); } } @OnLifecycleEvent(ON_STOP) private void detachScrollWatcher() { - mRecyclerView.removeOnScrollListener(mScrollChangeWatcher); + mScrollView.setOnScrollChangeListener(null); mIsScrollWatcherAttached = false; } /** * Update the drop shadow as the scrollable entity is scrolled. */ - final class ScrollChangeWatcher extends RecyclerView.OnScrollListener { + final class ScrollChangeWatcher implements View.OnScrollChangeListener { private final Activity mActivity; private final View mAnchorView; @@ -112,9 +107,9 @@ public class ActionBarShadowController implements LifecycleObserver { mActivity = null; } - // RecyclerView scrolled. @Override - public void onScrolled(RecyclerView view, int dx, int dy) { + public void onScrollChange(View view, int scrollX, int scrollY, int oldScrollX, + int oldScrollY) { updateDropShadow(view); } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionBarShadowControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionBarShadowControllerTest.java index a25b51298d3e..4e00ab5ce220 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionBarShadowControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionBarShadowControllerTest.java @@ -22,6 +22,7 @@ import static androidx.lifecycle.Lifecycle.Event.ON_STOP; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -49,6 +50,8 @@ public class ActionBarShadowControllerTest { @Mock private RecyclerView mRecyclerView; @Mock + private View mScrollView; + @Mock private Activity mActivity; @Mock private ActionBar mActionBar; @@ -66,51 +69,60 @@ public class ActionBarShadowControllerTest { } @Test - public void attachToRecyclerView_shouldAddScrollWatcherAndUpdateActionBar() { + public void attachToView_shouldAddScrollWatcherAndUpdateActionBar() { when(mRecyclerView.canScrollVertically(-1)).thenReturn(false); - ActionBarShadowController.attachToRecyclerView(mActivity, mLifecycle, mRecyclerView); + ActionBarShadowController.attachToView(mActivity, mLifecycle, mRecyclerView); + + verify(mActionBar).setElevation(ActionBarShadowController.ELEVATION_LOW); + } + + @Test + public void attachToView_scrollView_shouldAddScrollWatcherAndUpdateActionBar() { + when(mScrollView.canScrollVertically(-1)).thenReturn(false); + + ActionBarShadowController.attachToView(mActivity, mLifecycle, mScrollView); verify(mActionBar).setElevation(ActionBarShadowController.ELEVATION_LOW); } @Test - public void attachToRecyclerView_customViewAsActionBar_shouldUpdateElevationOnScroll() { + public void attachToView_customViewAsActionBar_shouldUpdateElevationOnScroll() { // Setup mView.setElevation(50); when(mRecyclerView.canScrollVertically(-1)).thenReturn(false); final ActionBarShadowController controller = - ActionBarShadowController.attachToRecyclerView(mView, mLifecycle, mRecyclerView); + ActionBarShadowController.attachToView(mView, mLifecycle, mRecyclerView); assertThat(mView.getElevation()).isEqualTo(ActionBarShadowController.ELEVATION_LOW); // Scroll when(mRecyclerView.canScrollVertically(-1)).thenReturn(true); - controller.mScrollChangeWatcher.onScrolled(mRecyclerView, 10 /* dx */, 10 /* dy */); + controller.mScrollChangeWatcher.onScrollChange(mRecyclerView, 10, 10, 0, 0); assertThat(mView.getElevation()).isEqualTo(ActionBarShadowController.ELEVATION_HIGH); } @Test - public void attachToRecyclerView_lifecycleChange_shouldAttachDetach() { - ActionBarShadowController.attachToRecyclerView(mActivity, mLifecycle, mRecyclerView); + public void attachToView_lifecycleChange_shouldAttachDetach() { + ActionBarShadowController.attachToView(mActivity, mLifecycle, mRecyclerView); - verify(mRecyclerView).addOnScrollListener(any()); + verify(mRecyclerView).setOnScrollChangeListener(any()); mLifecycle.handleLifecycleEvent(ON_START); mLifecycle.handleLifecycleEvent(ON_STOP); - verify(mRecyclerView).removeOnScrollListener(any()); + verify(mRecyclerView).setOnScrollChangeListener(isNull()); mLifecycle.handleLifecycleEvent(ON_START); - verify(mRecyclerView, times(2)).addOnScrollListener(any()); + verify(mRecyclerView, times(3)).setOnScrollChangeListener(any()); } @Test public void onScrolled_nullAnchorViewAndActivity_shouldNotCrash() { final Activity activity = null; final ActionBarShadowController controller = - ActionBarShadowController.attachToRecyclerView(activity, mLifecycle, mRecyclerView); + ActionBarShadowController.attachToView(activity, mLifecycle, mRecyclerView); // Scroll - controller.mScrollChangeWatcher.onScrolled(mRecyclerView, 10 /* dx */, 10 /* dy */); + controller.mScrollChangeWatcher.onScrollChange(mRecyclerView, 10, 10, 0, 0); // no crash } } |