Progressive disclosure on selected UIs: app, display
Bug: 32255863 Test: RunSettingsRoboTests Change-Id: I1651433ba30a2b5f880095e07b5e2ed9c4e308b9
This commit is contained in:
26
res/drawable/ic_arrow_down_24dp.xml
Normal file
26
res/drawable/ic_arrow_down_24dp.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2017 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorAccent">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M7.41,7.84L12,12.42l4.59,-4.58L18,9.25l-6,6 -6,-6z"/>
|
||||
</vector>
|
@@ -15,18 +15,63 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<!-- Based off frameworks/base/core/res/res/layout/preference_material.xml -->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/selectable_card_grey"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:orientation="vertical"
|
||||
android:paddingEnd="?android:attr/scrollbarSize">
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/icon_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="60dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp">
|
||||
<com.android.internal.widget.PreferenceImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxWidth="48dp"
|
||||
android:maxHeight="48dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:textColor="?android:attr/colorAccent"
|
||||
android:ellipsize="marquee"/>
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@android:id/title"
|
||||
android:layout_alignStart="@android:id/title"
|
||||
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:ellipsize="marquee"
|
||||
android:maxLines="1"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
@@ -6629,7 +6629,7 @@
|
||||
<string name="experimental_preference">(Experimental)</string>
|
||||
|
||||
<!-- [CHAR LIMIT=45] Auto-rotate setting title -->
|
||||
<string name="display_auto_rotate_title">When device is rotated</string>
|
||||
<string name="display_auto_rotate_title">Device rotation</string>
|
||||
<!-- [CHAR LIMIT=70] Rotate when screen is turned option -->
|
||||
<string name="display_auto_rotate_rotate">Rotate the contents of the screen</string>
|
||||
<!-- [CHAR LIMIT=70] Keep the screen in portrait when rotated -->
|
||||
|
@@ -61,6 +61,12 @@ public class DisplaySettings extends DashboardFragment {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
mProgressiveDisclosureMixin.setTileLimit(4);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCategoryKey() {
|
||||
return CategoryKey.CATEGORY_DISPLAY;
|
||||
|
@@ -16,7 +16,6 @@
|
||||
package com.android.settings.applications;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.provider.SearchIndexableResource;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
@@ -36,11 +35,6 @@ public class AdvancedAppSettings extends DashboardFragment {
|
||||
|
||||
static final String TAG = "AdvancedAppSettings";
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCategoryKey() {
|
||||
return CategoryKey.CATEGORY_APPS_DEFAULT;
|
||||
|
@@ -39,6 +39,12 @@ public class AppAndNotificationDashboardFragment extends DashboardFragment {
|
||||
return MetricsProto.MetricsEvent.SETTINGS_APP_NOTIF_CATEGORY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
mProgressiveDisclosureMixin.setTileLimit(3);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCategoryKey() {
|
||||
return CategoryKey.CATEGORY_APPS;
|
||||
|
@@ -268,6 +268,7 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
|
||||
|
||||
// Add resource based tiles.
|
||||
displayResourceTiles();
|
||||
mProgressiveDisclosureMixin.collapse(getPreferenceScreen());
|
||||
|
||||
refreshDashboardTiles(TAG);
|
||||
}
|
||||
|
@@ -47,6 +47,7 @@ public class ExpandPreference extends Preference {
|
||||
|
||||
private void init() {
|
||||
setLayoutResource(R.layout.expand_preference);
|
||||
setIcon(R.drawable.ic_arrow_down_24dp);
|
||||
setTitle(R.string.wifi_more);
|
||||
setOrder(999);
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ import android.support.v7.preference.PreferenceScreen;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settings.core.lifecycle.events.OnCreate;
|
||||
import com.android.settings.core.lifecycle.events.OnSaveInstanceState;
|
||||
@@ -40,18 +41,19 @@ public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickL
|
||||
private static final String STATE_USER_EXPANDED = "state_user_expanded";
|
||||
private static final int DEFAULT_TILE_LIMIT = 300;
|
||||
|
||||
private int mTileLimit = DEFAULT_TILE_LIMIT;
|
||||
|
||||
private final Context mContext;
|
||||
private final DashboardFeatureProvider mDashboardFeatureProvider;
|
||||
// Collapsed preference sorted by order.
|
||||
private final List<Preference> mCollapsedPrefs = new ArrayList<>();
|
||||
private final ExpandPreference mExpandButton;
|
||||
private /* final */ ExpandPreference mExpandButton;
|
||||
private final PreferenceFragment mFragment;
|
||||
|
||||
private int mTileLimit = DEFAULT_TILE_LIMIT;
|
||||
private boolean mUserExpanded;
|
||||
|
||||
public ProgressiveDisclosureMixin(Context context,
|
||||
DashboardFeatureProvider dashboardFeatureProvider, PreferenceFragment fragment) {
|
||||
mContext = context;
|
||||
mFragment = fragment;
|
||||
mExpandButton = new ExpandPreference(context);
|
||||
mExpandButton.setOnPreferenceClickListener(this);
|
||||
@@ -181,6 +183,8 @@ public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickL
|
||||
if (mCollapsedPrefs.isEmpty()) {
|
||||
// Removed last element, remove expand button too.
|
||||
screen.removePreference(mExpandButton);
|
||||
} else {
|
||||
updateExpandButtonSummary();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -216,10 +220,28 @@ public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickL
|
||||
insertionIndex = insertionIndex * -1 - 1;
|
||||
}
|
||||
mCollapsedPrefs.add(insertionIndex, preference);
|
||||
updateExpandButtonSummary();
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
List<Preference> getCollapsedPrefs() {
|
||||
return mCollapsedPrefs;
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
void updateExpandButtonSummary() {
|
||||
final int size = mCollapsedPrefs.size();
|
||||
if (size == 0) {
|
||||
mExpandButton.setSummary(null);
|
||||
} else if (size == 1) {
|
||||
mExpandButton.setSummary(mCollapsedPrefs.get(0).getTitle());
|
||||
} else {
|
||||
CharSequence summary = mCollapsedPrefs.get(0).getTitle();
|
||||
for (int i = 1; i < size; i++) {
|
||||
summary = mContext.getString(R.string.join_many_items_middle, summary,
|
||||
mCollapsedPrefs.get(i).getTitle());
|
||||
}
|
||||
mExpandButton.setSummary(summary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ import android.support.v14.preference.PreferenceFragment;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
@@ -34,6 +35,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -41,6 +43,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -56,10 +59,11 @@ public class ProgressiveDisclosureTest {
|
||||
private FakeFeatureFactory mFakeFeatureFactory;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private PreferenceFragment mPreferenceFragment;
|
||||
@Mock
|
||||
private ExpandPreference mExpandButton;
|
||||
private PreferenceScreen mScreen;
|
||||
private Context mAppContext;
|
||||
private Preference mPreference;
|
||||
|
||||
private ProgressiveDisclosureMixin mMixin;
|
||||
|
||||
@Before
|
||||
@@ -71,6 +75,7 @@ public class ProgressiveDisclosureTest {
|
||||
mFakeFeatureFactory = (FakeFeatureFactory) FeatureFactory.getFactory(mContext);
|
||||
mMixin = new ProgressiveDisclosureMixin(mAppContext,
|
||||
mFakeFeatureFactory.dashboardFeatureProvider, mPreferenceFragment);
|
||||
ReflectionHelpers.setField(mMixin, "mExpandButton", mExpandButton);
|
||||
mPreference = new Preference(mAppContext);
|
||||
mPreference.setKey("test");
|
||||
when(mFakeFeatureFactory.dashboardFeatureProvider.isEnabled()).thenReturn(true);
|
||||
@@ -166,6 +171,7 @@ public class ProgressiveDisclosureTest {
|
||||
|
||||
mMixin.collapse(screen);
|
||||
assertThat(mMixin.isCollapsed()).isFalse();
|
||||
verify(mExpandButton, never()).setSummary(anyString());
|
||||
verify(screen, never()).addPreference(any(Preference.class));
|
||||
verify(screen, never()).removePreference(any(Preference.class));
|
||||
}
|
||||
@@ -180,6 +186,7 @@ public class ProgressiveDisclosureTest {
|
||||
mMixin.collapse(screen);
|
||||
|
||||
assertThat(mMixin.isCollapsed()).isTrue();
|
||||
verify(mExpandButton, atLeastOnce()).setSummary(anyString());
|
||||
verify(screen).addPreference(any(ExpandPreference.class));
|
||||
verify(screen, times(3)).removePreference(any(Preference.class));
|
||||
}
|
||||
@@ -224,7 +231,9 @@ public class ProgressiveDisclosureTest {
|
||||
lastPref.setOrder(100);
|
||||
// Add something to collapsed list so we are in collapsed state.
|
||||
mMixin.addToCollapsedList(new Preference(mAppContext));
|
||||
verify(mExpandButton).setSummary(anyString());
|
||||
assertThat(mMixin.getCollapsedPrefs().size()).isEqualTo(1);
|
||||
|
||||
// 3 prefs on screen, 2 are real and the last one is more button.
|
||||
when(mScreen.getPreferenceCount()).thenReturn(3);
|
||||
when(mScreen.getPreference(1)).thenReturn(lastPref);
|
||||
@@ -244,7 +253,9 @@ public class ProgressiveDisclosureTest {
|
||||
lastPref.setOrder(100);
|
||||
// Add something to collapsed list so we are in collapsed state.
|
||||
mMixin.addToCollapsedList(new Preference(mAppContext));
|
||||
verify(mExpandButton).setSummary(anyString());
|
||||
assertThat(mMixin.getCollapsedPrefs().size()).isEqualTo(1);
|
||||
|
||||
// 3 prefs on screen, 2 are real and the last one is more button.
|
||||
when(mScreen.getPreferenceCount()).thenReturn(3);
|
||||
when(mScreen.getPreference(1)).thenReturn(lastPref);
|
||||
@@ -255,6 +266,40 @@ public class ProgressiveDisclosureTest {
|
||||
|
||||
verify(mScreen, never()).removePreference(any(Preference.class));
|
||||
verify(mScreen, never()).addPreference(any(Preference.class));
|
||||
verify(mExpandButton, times(2)).setSummary(anyString());
|
||||
assertThat(mMixin.getCollapsedPrefs().get(0)).isSameAs(toBeAdded);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateExpandSummary_noPref_noSummary() {
|
||||
mMixin.updateExpandButtonSummary();
|
||||
|
||||
verify(mExpandButton).setSummary(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateExapndSummary_singlePref_expandSummarySameAsPrefTitle() {
|
||||
final String TEST = "test";
|
||||
final Preference pref = new Preference(mAppContext);
|
||||
pref.setTitle(TEST);
|
||||
|
||||
mMixin.addToCollapsedList(pref);
|
||||
verify(mExpandButton).setSummary(TEST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateExapndSummary_multiPrefs_useCombinedPrefTitleAsSummary() {
|
||||
final String TEST1 = "test1";
|
||||
final String TEST2 = "test2";
|
||||
final Preference pref1 = new Preference(mAppContext);
|
||||
pref1.setTitle(TEST1);
|
||||
final Preference pref2 = new Preference(mAppContext);
|
||||
pref2.setTitle(TEST2);
|
||||
|
||||
mMixin.addToCollapsedList(pref1);
|
||||
mMixin.addToCollapsedList(pref2);
|
||||
|
||||
verify(mExpandButton)
|
||||
.setSummary(mAppContext.getString(R.string.join_many_items_middle, TEST1, TEST2));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user