Add shadow to searchbar when user scrolls vertically
Bug: 63528057
Test: robotests
Change-Id: Ib85676d78b43be38aab1eacd0820d0755a601f60
(cherry picked from commit e651ddf9e6c00a62338ef8c7114b5e5e9cd307ec)
diff --git a/res/layout/search_panel.xml b/res/layout/search_panel.xml
index 6d76001..48a1d4c 100644
--- a/res/layout/search_panel.xml
+++ b/res/layout/search_panel.xml
@@ -22,6 +22,7 @@
android:orientation="vertical">
<FrameLayout
+ android:id="@+id/search_bar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/suggestion_condition_background">
diff --git a/res/layout/settings_main_dashboard.xml b/res/layout/settings_main_dashboard.xml
index d62ae1d..95299ae 100644
--- a/res/layout/settings_main_dashboard.xml
+++ b/res/layout/settings_main_dashboard.xml
@@ -23,6 +23,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
+ android:id="@+id/search_bar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/suggestion_condition_background">
diff --git a/src/com/android/settings/dashboard/DashboardSummary.java b/src/com/android/settings/dashboard/DashboardSummary.java
index 809b83d..4d2bd66 100644
--- a/src/com/android/settings/dashboard/DashboardSummary.java
+++ b/src/com/android/settings/dashboard/DashboardSummary.java
@@ -40,6 +40,7 @@
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.dashboard.suggestions.SuggestionsChecks;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.widget.ActionBarShadowController;
import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.SettingsDrawerActivity;
@@ -192,12 +193,14 @@
mDashboard.setHasFixedSize(true);
mDashboard.addItemDecoration(new DashboardDecorator(getContext()));
mDashboard.setListener(this);
- Log.d(TAG, "adapter created");
mAdapter = new DashboardAdapter(getContext(), bundle, mConditionManager.getConditions(),
mSuggestionParser, this /* SuggestionDismissController.Callback */);
mDashboard.setAdapter(mAdapter);
mDashboard.setItemAnimator(new DashboardItemAnimator());
mSummaryLoader.setSummaryConsumer(mAdapter);
+ ActionBarShadowController.attachToRecyclerView(
+ getActivity().findViewById(R.id.search_bar_container), getLifecycle(), mDashboard);
+
if (DEBUG_TIMING) {
Log.d(TAG, "onViewCreated took "
+ (System.currentTimeMillis() - startTime) + " ms");
diff --git a/src/com/android/settings/dashboard/conditional/CellularDataCondition.java b/src/com/android/settings/dashboard/conditional/CellularDataCondition.java
index 6842422..64d263f 100644
--- a/src/com/android/settings/dashboard/conditional/CellularDataCondition.java
+++ b/src/com/android/settings/dashboard/conditional/CellularDataCondition.java
@@ -44,7 +44,7 @@
setActive(false);
return;
}
- setActive(!telephony.getDataEnabled());
+ setActive(!telephony.isDataEnabled());
}
@Override
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
index d9feae9..2171c2a 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
@@ -25,7 +25,6 @@
import android.support.annotation.NonNull;
import android.util.Log;
-import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.Settings.AmbientDisplayPickupSuggestionActivity;
import com.android.settings.Settings.AmbientDisplaySuggestionActivity;
@@ -54,7 +53,6 @@
private final SuggestionRanker mSuggestionRanker;
private final MetricsFeatureProvider mMetricsFeatureProvider;
- private final AmbientDisplayConfiguration mAmbientDisplayConfig;
@Override
public boolean isSmartSuggestionEnabled(Context context) {
@@ -96,7 +94,6 @@
new SuggestionFeaturizer(new EventStore(appContext)));
mMetricsFeatureProvider = FeatureFactory.getFactory(appContext)
.getMetricsFeatureProvider();
- mAmbientDisplayConfig = new AmbientDisplayConfiguration(appContext);
}
@Override
diff --git a/src/com/android/settings/search/SearchFragment.java b/src/com/android/settings/search/SearchFragment.java
index 7ceec62..69c2062 100644
--- a/src/com/android/settings/search/SearchFragment.java
+++ b/src/com/android/settings/search/SearchFragment.java
@@ -47,6 +47,7 @@
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.widget.ActionBarShadowController;
import java.util.ArrayList;
import java.util.Arrays;
@@ -202,6 +203,8 @@
params.setMarginStart(0);
editFrame.setLayoutParams(params);
}
+ ActionBarShadowController.attachToRecyclerView(
+ view.findViewById(R.id.search_bar_container), getLifecycle(), mResultsRecyclerView);
return view;
}
diff --git a/src/com/android/settings/widget/ActionBarShadowController.java b/src/com/android/settings/widget/ActionBarShadowController.java
index 75bdf0e..0c6b02f 100644
--- a/src/com/android/settings/widget/ActionBarShadowController.java
+++ b/src/com/android/settings/widget/ActionBarShadowController.java
@@ -18,6 +18,7 @@
import android.app.ActionBar;
import android.app.Activity;
+import android.support.annotation.VisibleForTesting;
import android.support.v7.widget.RecyclerView;
import android.view.View;
@@ -26,9 +27,20 @@
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
+/**
+ * A controller that adds shadow to actionbar when content view scrolls.
+ * <p/>
+ * It also works on custom views acting as an actionbar.
+ */
public class ActionBarShadowController implements LifecycleObserver, OnStart, OnStop {
- private ScrollChangeWatcher mScrollChangeWatcher;
+ @VisibleForTesting
+ static final float ELEVATION_HIGH = 8;
+ @VisibleForTesting
+ static final float ELEVATION_LOW = 0;
+
+ @VisibleForTesting
+ ScrollChangeWatcher mScrollChangeWatcher;
private RecyclerView mRecyclerView;
private boolean isScrollWatcherAttached;
@@ -37,6 +49,11 @@
return new ActionBarShadowController(activity, lifecycle, recyclerView);
}
+ public static ActionBarShadowController attachToRecyclerView(View anchorView,
+ Lifecycle lifecycle, RecyclerView recyclerView) {
+ return new ActionBarShadowController(anchorView, lifecycle, recyclerView);
+ }
+
private ActionBarShadowController(Activity activity, Lifecycle lifecycle,
RecyclerView recyclerView) {
mScrollChangeWatcher = new ScrollChangeWatcher(activity);
@@ -45,6 +62,14 @@
lifecycle.addObserver(this);
}
+ private ActionBarShadowController(View anchorView, Lifecycle lifecycle,
+ RecyclerView recyclerView) {
+ mScrollChangeWatcher = new ScrollChangeWatcher(anchorView);
+ mRecyclerView = recyclerView;
+ attachScrollWatcher();
+ lifecycle.addObserver(this);
+ }
+
@Override
public void onStop() {
detachScrollWatcher();
@@ -71,12 +96,19 @@
/**
* Update the drop shadow as the scrollable entity is scrolled.
*/
- private final class ScrollChangeWatcher extends RecyclerView.OnScrollListener {
+ final class ScrollChangeWatcher extends RecyclerView.OnScrollListener {
- private Activity mActivity;
+ private final Activity mActivity;
+ private final View mAnchorView;
public ScrollChangeWatcher(Activity activity) {
mActivity = activity;
+ mAnchorView = null;
+ }
+
+ public ScrollChangeWatcher(View anchorView) {
+ mAnchorView = anchorView;
+ mActivity = null;
}
// RecyclerView scrolled.
@@ -87,9 +119,13 @@
public void updateDropShadow(View view) {
final boolean shouldShowShadow = view.canScrollVertically(-1);
- final ActionBar actionBar = mActivity.getActionBar();
- if (actionBar != null) {
- actionBar.setElevation(shouldShowShadow ? 8 : 0);
+ if (mAnchorView != null) {
+ mAnchorView.setElevation(shouldShowShadow ? ELEVATION_HIGH : ELEVATION_LOW);
+ } else {
+ final ActionBar actionBar = mActivity.getActionBar();
+ if (actionBar != null) {
+ actionBar.setElevation(shouldShowShadow ? ELEVATION_HIGH : ELEVATION_LOW);
+ }
}
}
}
diff --git a/tests/robotests/src/com/android/settings/widget/ActionBarShadowControllerTest.java b/tests/robotests/src/com/android/settings/widget/ActionBarShadowControllerTest.java
index 2fbf03e..be50d77 100644
--- a/tests/robotests/src/com/android/settings/widget/ActionBarShadowControllerTest.java
+++ b/tests/robotests/src/com/android/settings/widget/ActionBarShadowControllerTest.java
@@ -17,12 +17,19 @@
package com.android.settings.widget;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.app.ActionBar;
import android.app.Activity;
import android.support.v7.widget.RecyclerView;
+import android.view.View;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -31,17 +38,12 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
import java.util.List;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class ActionBarShadowControllerTest {
@@ -53,11 +55,13 @@
@Mock
private ActionBar mActionBar;
private Lifecycle mLifecycle;
+ private View mView;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mActivity.getActionBar()).thenReturn(mActionBar);
+ mView = new View(RuntimeEnvironment.application);
mLifecycle = new Lifecycle();
}
@@ -67,9 +71,23 @@
ActionBarShadowController.attachToRecyclerView(mActivity, mLifecycle, mRecyclerView);
- verify(mActionBar).setElevation(0);
+ verify(mActionBar).setElevation(ActionBarShadowController.ELEVATION_LOW);
}
+ @Test
+ public void attachToRecyclerView_customViewAsActionBar_shouldUpdateElevationOnScroll() {
+ // Setup
+ mView.setElevation(50);
+ when(mRecyclerView.canScrollVertically(-1)).thenReturn(false);
+ final ActionBarShadowController controller =
+ ActionBarShadowController.attachToRecyclerView(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 */);
+ assertThat(mView.getElevation()).isEqualTo(ActionBarShadowController.ELEVATION_HIGH);
+ }
@Test
public void attachToRecyclerView_lifecycleChange_shouldAttachDetach() {