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">
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">
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;
mDashboard.setLayoutManager(mLayoutManager);
mDashboard.setHasFixedSize(true);
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");
setActive(false);
return;
}
- setActive(!telephony.getDataEnabled());
+ setActive(!telephony.isDataEnabled());
}
@Override
import android.text.format.DateUtils;
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;
private final SuggestionRanker mSuggestionRanker;
private final MetricsFeatureProvider mMetricsFeatureProvider;
- private final AmbientDisplayConfiguration mAmbientDisplayConfig;
@Override
public boolean isSuggestionEnabled(Context context) {
new SuggestionFeaturizer(new EventStore(appContext)));
mMetricsFeatureProvider = FeatureFactory.getFactory(appContext)
.getMetricsFeatureProvider();
- mAmbientDisplayConfig = new AmbientDisplayConfiguration(appContext);
}
@Override
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;
params.setMarginStart(0);
editFrame.setLayoutParams(params);
}
+ ActionBarShadowController.attachToRecyclerView(
+ view.findViewById(R.id.search_bar_container), getLifecycle(), mResultsRecyclerView);
return view;
}
import android.app.ActionBar;
import android.app.Activity;
+import android.support.annotation.VisibleForTesting;
import android.support.v7.widget.RecyclerView;
import android.view.View;
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;
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);
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();
/**
* 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.
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);
+ }
}
}
}
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;
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 {
@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();
}
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() {