Progressive disclosure on selected UIs: app, display

Bug: 32255863
Test: RunSettingsRoboTests
Change-Id: I1651433ba30a2b5f880095e07b5e2ed9c4e308b9
This commit is contained in:
Fan Zhang
2017-01-06 16:10:28 -08:00
parent 63e8d160f9
commit d916dae218
10 changed files with 165 additions and 19 deletions

View 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>

View File

@@ -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>

View File

@@ -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 -->

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -268,6 +268,7 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
// Add resource based tiles.
displayResourceTiles();
mProgressiveDisclosureMixin.collapse(getPreferenceScreen());
refreshDashboardTiles(TAG);
}

View File

@@ -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);
}

View File

@@ -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);
}
}
}

View File

@@ -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));
}
}