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 68ba5fbd120f5..be3365fcc5ff1 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 a25b51298d3eb..4e00ab5ce2203 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 attachToRecyclerView_customViewAsActionBar_shouldUpdateElevationOnScroll() { + 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 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 } }