diff --git a/res/drawable/homepage_highlighted_item_background.xml b/res/drawable/homepage_highlighted_item_background.xml
index b7b24e991a1..d54ff601643 100644
--- a/res/drawable/homepage_highlighted_item_background.xml
+++ b/res/drawable/homepage_highlighted_item_background.xml
@@ -14,13 +14,10 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/homepage_selectable_item_background.xml b/res/drawable/homepage_selectable_item_background.xml
new file mode 100644
index 00000000000..f5e17ea69b7
--- /dev/null
+++ b/res/drawable/homepage_selectable_item_background.xml
@@ -0,0 +1,27 @@
+
+
+
+ -
+
+
+
+
+
+
diff --git a/res/layout/homepage_preference.xml b/res/layout/homepage_preference.xml
index 62f6457d27f..59dc7c4b176 100644
--- a/res/layout/homepage_preference.xml
+++ b/res/layout/homepage_preference.xml
@@ -20,10 +20,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ android:minHeight="@dimen/homepage_preference_min_height"
android:gravity="center_vertical"
- android:paddingStart="@dimen/homepage_menu_entry_padding_horizontal"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/selectableItemBackground"
android:clipToPadding="false"
android:baselineAligned="false">
@@ -32,11 +30,10 @@
android:id="@+id/icon_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:minWidth="56dp"
- android:gravity="center"
+ android:minWidth="48dp"
+ android:gravity="end|center_vertical"
android:orientation="horizontal"
- android:paddingStart="8dp"
- android:paddingEnd="8dp"
+ android:paddingStart="@dimen/homepage_preference_icon_padding_start"
android:paddingTop="4dp"
android:paddingBottom="4dp">
@@ -44,18 +41,20 @@
android:id="@android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- app:maxWidth="40dp"
- app:maxHeight="40dp"/>
+ app:maxWidth="48dp"
+ app:maxHeight="48dp"/>
+ android:paddingStart="@dimen/homepage_preference_text_padding_start"
+ android:paddingEnd="24dp">
-
\ No newline at end of file
+
diff --git a/res/layout/search_bar.xml b/res/layout/search_bar.xml
index 7cdf04dbd14..dfc9596d9fc 100644
--- a/res/layout/search_bar.xml
+++ b/res/layout/search_bar.xml
@@ -31,7 +31,8 @@
android:id="@+id/search_action_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/search_bar_height"
- android:paddingStart="4dp"
+ android:paddingStart="@dimen/search_bar_padding_start"
+ android:paddingEnd="@dimen/search_bar_padding_end"
android:background="@drawable/search_bar_selected_background"
android:contentInsetStartWithNavigation="@dimen/search_bar_content_inset"
android:navigationIcon="@drawable/ic_homepage_search">
@@ -40,7 +41,7 @@
style="@style/TextAppearance.SearchBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingStart="-4dp"
+ android:paddingStart="@dimen/search_bar_title_padding_start"
android:layout_gravity="start"
android:text="@string/search_menu"/>
diff --git a/res/layout/search_bar_two_pane_version.xml b/res/layout/search_bar_two_pane_version.xml
index a869853d4bc..ede57226699 100644
--- a/res/layout/search_bar_two_pane_version.xml
+++ b/res/layout/search_bar_two_pane_version.xml
@@ -21,20 +21,23 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:layout_margin="@dimen/search_bar_margin">
+ android:layout_marginEnd="@dimen/search_bar_margin"
+ android:layout_marginVertical="@dimen/search_bar_margin">
diff --git a/res/layout/settings_homepage_app_bar_two_pane_layout.xml b/res/layout/settings_homepage_app_bar_two_pane_layout.xml
index 4178632603a..4db2e652501 100644
--- a/res/layout/settings_homepage_app_bar_two_pane_layout.xml
+++ b/res/layout/settings_homepage_app_bar_two_pane_layout.xml
@@ -20,7 +20,6 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
android:background="?androidprv:attr/colorSurface"
android:orientation="vertical">
@@ -41,7 +40,6 @@
android:layout_width="@dimen/avatar_length"
android:layout_height="@dimen/avatar_length"
android:layout_gravity="center"
- android:layout_marginEnd="16dp"
android:contentDescription="@string/search_bar_account_avatar_content_description"/>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index db1fbbc9be8..2e821e011e6 100755
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -35,9 +35,6 @@
80dp
- 64dp
- 32dp
-
24dp
24dp
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 8a59da2844b..2e4d8be77f7 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -129,6 +129,12 @@
20sp
28dp
56dp
+ 4dp
+ 8dp
+ 16dp
+ 24dp
+ -4dp
+ 8dp
48dp
@@ -136,13 +142,16 @@
24dp
20dp
-
+
8dp
24dp
-
-
- 16dp
- 28dp
+ 24dp
+ 28dp
+ 88sp
+ 32dp
+ 8dp
+ 16dp
+ 24dp
16dp
diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
index 38af8d679cf..fdf13142cb8 100644
--- a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
+++ b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
@@ -16,6 +16,7 @@
package com.android.settings.activityembedding;
+import android.app.Activity;
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.FeatureFlagUtils;
@@ -33,6 +34,8 @@ public class ActivityEmbeddingUtils {
// The smallest value of the smallest-width (sw) of the window in any rotation when
// the split should be used.
private static final float MIN_SMALLEST_SCREEN_SPLIT_WIDTH_DP = 600f;
+ // The minimum width of the activity to show the regular homepage layout.
+ private static final float MIN_REGULAR_HOMEPAGE_LAYOUT_WIDTH_DP = 380f;
private static final String TAG = "ActivityEmbeddingUtils";
/** Get the smallest pixel value of width of the window when the split should be used. */
@@ -71,4 +74,11 @@ public class ActivityEmbeddingUtils {
return isFlagEnabled && isSplitSupported;
}
+
+ /** Whether to show the regular or simplified homepage layout. */
+ public static boolean isRegularHomepageLayout(Activity activity) {
+ DisplayMetrics dm = activity.getResources().getDisplayMetrics();
+ return dm.widthPixels >= (int) TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP, MIN_REGULAR_HOMEPAGE_LAYOUT_WIDTH_DP, dm);
+ }
}
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index 7aeea114c39..038f6727c64 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -86,6 +86,7 @@ public class SettingsHomepageActivity extends FragmentActivity implements
private TopLevelSettings mMainFragment;
private View mHomepageView;
+ private View mAppBar;
private View mSuggestionView;
private View mTwoPaneSuggestionView;
private CategoryMixin mCategoryMixin;
@@ -93,6 +94,8 @@ public class SettingsHomepageActivity extends FragmentActivity implements
private SplitController mSplitController;
private boolean mIsEmbeddingActivityEnabled;
private boolean mIsTwoPane;
+ // A regular layout shows icons on homepage, whereas a simplified layout doesn't.
+ private boolean mIsRegularLayout = true;
/** A listener receiving homepage loaded events. */
public interface HomepageLoadedListener {
@@ -100,8 +103,11 @@ public class SettingsHomepageActivity extends FragmentActivity implements
void onHomepageLoaded();
}
- private interface FragmentBuilder {
- T build();
+ private interface FragmentCreator {
+ T create();
+
+ /** To initialize after {@link #create} */
+ default void init(Fragment fragment) {}
}
/**
@@ -145,6 +151,11 @@ public class SettingsHomepageActivity extends FragmentActivity implements
return mMainFragment;
}
+ /** Whether the activity is showing in two-pane */
+ public boolean isTwoPane() {
+ return mIsTwoPane;
+ }
+
@Override
public CategoryMixin getCategoryMixin() {
return mCategoryMixin;
@@ -160,8 +171,8 @@ public class SettingsHomepageActivity extends FragmentActivity implements
mSplitController = SplitController.getInstance();
mIsTwoPane = mSplitController.isActivityEmbedded(this);
- final View appBar = findViewById(R.id.app_bar_container);
- appBar.setMinimumHeight(getSearchBoxHeight());
+ mAppBar = findViewById(R.id.app_bar_container);
+ mAppBar.setMinimumHeight(getSearchBoxHeight());
initHomepageContainer();
updateHomepageAppBar();
updateHomepageBackground();
@@ -195,6 +206,8 @@ public class SettingsHomepageActivity extends FragmentActivity implements
// Launch the intent from deep link for large screen devices.
launchDeepLinkIntentToRight();
+ updateHomepagePaddings();
+ updateSplitLayout();
}
@Override
@@ -226,7 +239,42 @@ public class SettingsHomepageActivity extends FragmentActivity implements
mIsTwoPane = newTwoPaneState;
updateHomepageAppBar();
updateHomepageBackground();
+ updateHomepagePaddings();
}
+ updateSplitLayout();
+ }
+
+ private void updateSplitLayout() {
+ if (!mIsEmbeddingActivityEnabled) {
+ return;
+ }
+
+ if (mIsTwoPane) {
+ if (mIsRegularLayout == ActivityEmbeddingUtils.isRegularHomepageLayout(this)) {
+ // Layout unchanged
+ return;
+ }
+ } else if (mIsRegularLayout) {
+ // One pane mode with the regular layout, not needed to change
+ return;
+ }
+ mIsRegularLayout = !mIsRegularLayout;
+
+ // Update search title padding
+ View searchTitle = findViewById(R.id.search_bar_title);
+ if (searchTitle != null) {
+ int paddingStart = getResources().getDimensionPixelSize(
+ mIsRegularLayout
+ ? R.dimen.search_bar_title_padding_start_regular_two_pane
+ : R.dimen.search_bar_title_padding_start);
+ searchTitle.setPaddingRelative(paddingStart, 0, 0, 0);
+ }
+ // Notify fragments
+ getSupportFragmentManager().getFragments().forEach(fragment -> {
+ if (fragment instanceof SplitLayoutListener) {
+ ((SplitLayoutListener) fragment).onSplitLayoutChanged(mIsRegularLayout);
+ }
+ });
}
private void setupEdgeToEdge() {
@@ -303,29 +351,25 @@ public class SettingsHomepageActivity extends FragmentActivity implements
// Schedule a timer to show the homepage and hide the suggestion on timeout.
mHomepageView.postDelayed(() -> showHomepageWithSuggestion(false),
HOMEPAGE_LOADING_TIMEOUT_MS);
- final FragmentBuilder> fragmentBuilder = () -> {
- try {
- return fragmentClass.getConstructor().newInstance();
- } catch (Exception e) {
- Log.w(TAG, "Cannot show fragment", e);
- }
- return null;
- };
- showFragment(fragmentBuilder, R.id.suggestion_content);
+ showFragment(new SuggestionFragCreator(fragmentClass, /* isTwoPaneLayout= */ false),
+ R.id.suggestion_content);
if (mIsEmbeddingActivityEnabled) {
- showFragment(fragmentBuilder, R.id.two_pane_suggestion_content);
+ showFragment(new SuggestionFragCreator(fragmentClass, /* isTwoPaneLayout= */ true),
+ R.id.two_pane_suggestion_content);
}
}
- private T showFragment(FragmentBuilder fragmentBuilder, int id) {
+ private T showFragment(FragmentCreator fragmentCreator, int id) {
final FragmentManager fragmentManager = getSupportFragmentManager();
final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
T showFragment = (T) fragmentManager.findFragmentById(id);
if (showFragment == null) {
- showFragment = fragmentBuilder.build();
+ showFragment = fragmentCreator.create();
+ fragmentCreator.init(showFragment);
fragmentTransaction.add(id, showFragment);
} else {
+ fragmentCreator.init(showFragment);
fragmentTransaction.show(showFragment);
}
fragmentTransaction.commit();
@@ -447,9 +491,54 @@ public class SettingsHomepageActivity extends FragmentActivity implements
}
}
+ private void updateHomepagePaddings() {
+ if (!mIsEmbeddingActivityEnabled) {
+ return;
+ }
+ if (mIsTwoPane) {
+ int padding = getResources().getDimensionPixelSize(
+ R.dimen.homepage_padding_horizontal_two_pane);
+ mAppBar.setPaddingRelative(padding, 0, padding, 0);
+ mMainFragment.setPaddingHorizontal(padding);
+ } else {
+ mAppBar.setPaddingRelative(0, 0, 0, 0);
+ mMainFragment.setPaddingHorizontal(0);
+ }
+ mMainFragment.updatePreferencePadding(mIsTwoPane);
+ }
+
private int getSearchBoxHeight() {
final int searchBarHeight = getResources().getDimensionPixelSize(R.dimen.search_bar_height);
final int searchBarMargin = getResources().getDimensionPixelSize(R.dimen.search_bar_margin);
return searchBarHeight + searchBarMargin * 2;
}
+
+ private static class SuggestionFragCreator implements FragmentCreator {
+
+ private final Class extends Fragment> mClass;
+ private final boolean mIsTwoPaneLayout;
+
+ SuggestionFragCreator(Class extends Fragment> clazz, boolean isTwoPaneLayout) {
+ mClass = clazz;
+ mIsTwoPaneLayout = isTwoPaneLayout;
+ }
+
+ @Override
+ public Fragment create() {
+ try {
+ Fragment fragment = mClass.getConstructor().newInstance();
+ return fragment;
+ } catch (Exception e) {
+ Log.w(TAG, "Cannot show fragment", e);
+ }
+ return null;
+ }
+
+ @Override
+ public void init(Fragment fragment) {
+ if (fragment instanceof SplitLayoutListener) {
+ ((SplitLayoutListener) fragment).setSplitLayoutSupported(mIsTwoPaneLayout);
+ }
+ }
+ }
}
diff --git a/src/com/android/settings/homepage/SplitLayoutListener.java b/src/com/android/settings/homepage/SplitLayoutListener.java
new file mode 100644
index 00000000000..63f4bc4e862
--- /dev/null
+++ b/src/com/android/settings/homepage/SplitLayoutListener.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package com.android.settings.homepage;
+
+/** A listener receiving the spilt layout change */
+public interface SplitLayoutListener {
+
+ /**
+ * Called when the spilt layout is changed.
+ *
+ * @param isRegularLayout whether the layout should be regular or simplified
+ */
+ void onSplitLayoutChanged(boolean isRegularLayout);
+
+ /**
+ * Notifies the listener whether the split layout is supported.
+ */
+ default void setSplitLayoutSupported(boolean supported) {
+ }
+}
diff --git a/src/com/android/settings/homepage/TopLevelSettings.java b/src/com/android/settings/homepage/TopLevelSettings.java
index 334462b0b46..8623509ce9b 100644
--- a/src/com/android/settings/homepage/TopLevelSettings.java
+++ b/src/com/android/settings/homepage/TopLevelSettings.java
@@ -27,6 +27,8 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
@@ -44,12 +46,13 @@ import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.support.SupportPreferenceController;
import com.android.settings.widget.HomepagePreference;
+import com.android.settings.widget.HomepagePreferenceLayoutHelper.HomepagePreferenceLayout;
import com.android.settingslib.core.instrumentation.Instrumentable;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.search.SearchIndexable;
@SearchIndexable(forTarget = MOBILE)
-public class TopLevelSettings extends DashboardFragment implements
+public class TopLevelSettings extends DashboardFragment implements SplitLayoutListener,
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
private static final String TAG = "TopLevelSettings";
@@ -58,6 +61,7 @@ public class TopLevelSettings extends DashboardFragment implements
private boolean mIsEmbeddingActivityEnabled;
private TopLevelHighlightMixin mHighlightMixin;
+ private int mPaddingHorizontal;
private boolean mScrollNeeded = true;
private boolean mFirstStarted = true;
@@ -177,23 +181,13 @@ public class TopLevelSettings extends DashboardFragment implements
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
- final PreferenceScreen screen = getPreferenceScreen();
- if (screen == null) {
- return;
- }
- // Tint the homepage icons
- final int tintColor = Utils.getHomepageIconColor(getContext());
- final int count = screen.getPreferenceCount();
- for (int i = 0; i < count; i++) {
- final Preference preference = screen.getPreference(i);
- if (preference == null) {
- break;
- }
- final Drawable icon = preference.getIcon();
+ int tintColor = Utils.getHomepageIconColor(getContext());
+ iteratePreferences(preference -> {
+ Drawable icon = preference.getIcon();
if (icon != null) {
icon.setTint(tintColor);
}
- }
+ });
}
@Override
@@ -202,6 +196,15 @@ public class TopLevelSettings extends DashboardFragment implements
highlightPreferenceIfNeeded();
}
+ @Override
+ public void onSplitLayoutChanged(boolean isRegularLayout) {
+ iteratePreferences(preference -> {
+ if (preference instanceof HomepagePreferenceLayout) {
+ ((HomepagePreferenceLayout) preference).getHelper().setIconVisible(isRegularLayout);
+ }
+ });
+ }
+
@Override
public void highlightPreferenceIfNeeded() {
if (mHighlightMixin != null) {
@@ -209,6 +212,52 @@ public class TopLevelSettings extends DashboardFragment implements
}
}
+ @Override
+ public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
+ Bundle savedInstanceState) {
+ RecyclerView recyclerView = super.onCreateRecyclerView(inflater, parent,
+ savedInstanceState);
+ recyclerView.setPadding(mPaddingHorizontal, 0, mPaddingHorizontal, 0);
+ return recyclerView;
+ }
+
+ /** Sets the horizontal padding */
+ public void setPaddingHorizontal(int padding) {
+ mPaddingHorizontal = padding;
+ RecyclerView recyclerView = getListView();
+ if (recyclerView != null) {
+ recyclerView.setPadding(padding, 0, padding, 0);
+ }
+ }
+
+ /** Updates the preference internal paddings */
+ public void updatePreferencePadding(boolean isTwoPane) {
+ iteratePreferences(new PreferenceJob() {
+ private int mIconPaddingStart;
+ private int mTextPaddingStart;
+
+ @Override
+ public void init() {
+ mIconPaddingStart = getResources().getDimensionPixelSize(isTwoPane
+ ? R.dimen.homepage_preference_icon_padding_start_two_pane
+ : R.dimen.homepage_preference_icon_padding_start);
+ mTextPaddingStart = getResources().getDimensionPixelSize(isTwoPane
+ ? R.dimen.homepage_preference_text_padding_start_two_pane
+ : R.dimen.homepage_preference_text_padding_start);
+ }
+
+ @Override
+ public void doForEach(Preference preference) {
+ if (preference instanceof HomepagePreferenceLayout) {
+ ((HomepagePreferenceLayout) preference).getHelper()
+ .setIconPaddingStart(mIconPaddingStart);
+ ((HomepagePreferenceLayout) preference).getHelper()
+ .setTextPaddingStart(mTextPaddingStart);
+ }
+ }
+ });
+ }
+
/** Returns a {@link TopLevelHighlightMixin} that performs highlighting */
public TopLevelHighlightMixin getHighlightMixin() {
return mHighlightMixin;
@@ -261,6 +310,31 @@ public class TopLevelSettings extends DashboardFragment implements
}
}
+ private void iteratePreferences(PreferenceJob job) {
+ if (job == null || getPreferenceManager() == null) {
+ return;
+ }
+ PreferenceScreen screen = getPreferenceScreen();
+ if (screen == null) {
+ return;
+ }
+
+ job.init();
+ int count = screen.getPreferenceCount();
+ for (int i = 0; i < count; i++) {
+ Preference preference = screen.getPreference(i);
+ if (preference == null) {
+ break;
+ }
+ job.doForEach(preference);
+ }
+ }
+
+ private interface PreferenceJob {
+ default void init() {}
+ void doForEach(Preference preference);
+ }
+
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.top_level_settings) {
diff --git a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
index 911aabb13b8..338be483b6d 100644
--- a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
+++ b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
@@ -21,7 +21,6 @@ import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
-import android.util.TypedValue;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
@@ -46,6 +45,10 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
private static final String TAG = "HighlightableTopLevelAdapter";
static final long DELAY_HIGHLIGHT_DURATION_MILLIS = 100L;
+ private static final int RES_NORMAL_BACKGROUND =
+ R.drawable.homepage_selectable_item_background;
+ private static final int RES_HIGHLIGHTED_BACKGROUND =
+ R.drawable.homepage_highlighted_item_background;
private final int mTitleColorNormal;
private final int mTitleColorHighlight;
@@ -54,11 +57,8 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
private final int mIconColorNormal;
private final int mIconColorHighlight;
- private final Context mContext;
private final SettingsHomepageActivity mHomepageActivity;
private final RecyclerView mRecyclerView;
- private final int mNormalBackgroundRes;
- private final int mHighlightBackgroundRes;
private String mHighlightKey;
private int mHighlightPosition = RecyclerView.NO_POSITION;
private int mScrollPosition = RecyclerView.NO_POSITION;
@@ -74,23 +74,18 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
mHighlightKey = key;
mScrolled = !scrollNeeded;
mViewHolders = new SparseArray<>();
- mContext = preferenceGroup.getContext();
mHomepageActivity = homepageActivity;
- final TypedValue outValue = new TypedValue();
- mContext.getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
- outValue, true /* resolveRefs */);
- mNormalBackgroundRes = outValue.resourceId;
- mHighlightBackgroundRes = R.drawable.homepage_highlighted_item_background;
- mTitleColorNormal = Utils.getColorAttrDefaultColor(mContext,
+ Context context = preferenceGroup.getContext();
+ mTitleColorNormal = Utils.getColorAttrDefaultColor(context,
android.R.attr.textColorPrimary);
- mTitleColorHighlight = Utils.getColorAttrDefaultColor(mContext,
+ mTitleColorHighlight = Utils.getColorAttrDefaultColor(context,
android.R.attr.textColorPrimaryInverse);
- mSummaryColorNormal = Utils.getColorAttrDefaultColor(mContext,
+ mSummaryColorNormal = Utils.getColorAttrDefaultColor(context,
android.R.attr.textColorSecondary);
- mSummaryColorHighlight = Utils.getColorAttrDefaultColor(mContext,
+ mSummaryColorHighlight = Utils.getColorAttrDefaultColor(context,
android.R.attr.textColorSecondaryInverse);
- mIconColorNormal = Utils.getHomepageIconColor(mContext);
- mIconColorHighlight = Utils.getHomepageIconColorHighlight(mContext);
+ mIconColorNormal = Utils.getHomepageIconColor(context);
+ mIconColorHighlight = Utils.getHomepageIconColorHighlight(context);
}
@Override
@@ -236,7 +231,7 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
private void addHighlightBackground(PreferenceViewHolder holder) {
final View v = holder.itemView;
- v.setBackgroundResource(mHighlightBackgroundRes);
+ v.setBackgroundResource(RES_HIGHLIGHTED_BACKGROUND);
((TextView) v.findViewById(android.R.id.title)).setTextColor(mTitleColorHighlight);
((TextView) v.findViewById(android.R.id.summary)).setTextColor(mSummaryColorHighlight);
final Drawable drawable = ((ImageView) v.findViewById(android.R.id.icon)).getDrawable();
@@ -247,7 +242,7 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
private void removeHighlightBackground(PreferenceViewHolder holder) {
final View v = holder.itemView;
- v.setBackgroundResource(mNormalBackgroundRes);
+ v.setBackgroundResource(RES_NORMAL_BACKGROUND);
((TextView) v.findViewById(android.R.id.title)).setTextColor(mTitleColorNormal);
((TextView) v.findViewById(android.R.id.summary)).setTextColor(mSummaryColorNormal);
final Drawable drawable = ((ImageView) v.findViewById(android.R.id.icon)).getDrawable();
diff --git a/src/com/android/settings/widget/HomepagePreference.java b/src/com/android/settings/widget/HomepagePreference.java
index ff4055ee226..d0780622631 100644
--- a/src/com/android/settings/widget/HomepagePreference.java
+++ b/src/com/android/settings/widget/HomepagePreference.java
@@ -20,29 +20,43 @@ import android.content.Context;
import android.util.AttributeSet;
import androidx.preference.Preference;
-
-import com.android.settings.R;
+import androidx.preference.PreferenceViewHolder;
/** A customized layout for homepage preference. */
-public class HomepagePreference extends Preference {
+public class HomepagePreference extends Preference implements
+ HomepagePreferenceLayoutHelper.HomepagePreferenceLayout {
+
+ private final HomepagePreferenceLayoutHelper mHelper;
+
public HomepagePreference(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- setLayoutResource(R.layout.homepage_preference);
+ mHelper = new HomepagePreferenceLayoutHelper(this);
}
public HomepagePreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- setLayoutResource(R.layout.homepage_preference);
+ mHelper = new HomepagePreferenceLayoutHelper(this);
}
public HomepagePreference(Context context, AttributeSet attrs) {
super(context, attrs);
- setLayoutResource(R.layout.homepage_preference);
+ mHelper = new HomepagePreferenceLayoutHelper(this);
}
public HomepagePreference(Context context) {
super(context);
- setLayoutResource(R.layout.homepage_preference);
+ mHelper = new HomepagePreferenceLayoutHelper(this);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+ mHelper.onBindViewHolder(holder);
+ }
+
+ @Override
+ public HomepagePreferenceLayoutHelper getHelper() {
+ return mHelper;
}
}
diff --git a/src/com/android/settings/widget/HomepagePreferenceLayoutHelper.java b/src/com/android/settings/widget/HomepagePreferenceLayoutHelper.java
new file mode 100644
index 00000000000..6242e23000c
--- /dev/null
+++ b/src/com/android/settings/widget/HomepagePreferenceLayoutHelper.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package com.android.settings.widget;
+
+import android.view.View;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settings.R;
+
+/** Helper for homepage preference to manage layout. */
+public class HomepagePreferenceLayoutHelper {
+
+ private View mIcon;
+ private View mText;
+ private boolean mIconVisible = true;
+ private int mIconPaddingStart = -1;
+ private int mTextPaddingStart = -1;
+
+ /** The interface for managing preference layouts on homepage */
+ public interface HomepagePreferenceLayout {
+ /** Returns a {@link HomepagePreferenceLayoutHelper} */
+ HomepagePreferenceLayoutHelper getHelper();
+ }
+
+ public HomepagePreferenceLayoutHelper(Preference preference) {
+ preference.setLayoutResource(R.layout.homepage_preference);
+ }
+
+ /** Sets whether the icon should be visible */
+ public void setIconVisible(boolean visible) {
+ mIconVisible = visible;
+ if (mIcon != null) {
+ mIcon.setVisibility(visible ? View.VISIBLE : View.GONE);
+ }
+ }
+
+ /** Sets the icon padding start */
+ public void setIconPaddingStart(int paddingStart) {
+ mIconPaddingStart = paddingStart;
+ if (mIcon != null && paddingStart >= 0) {
+ mIcon.setPaddingRelative(paddingStart, mIcon.getPaddingTop(), mIcon.getPaddingEnd(),
+ mIcon.getPaddingBottom());
+ }
+ }
+
+ /** Sets the text padding start */
+ public void setTextPaddingStart(int paddingStart) {
+ mTextPaddingStart = paddingStart;
+ if (mText != null && paddingStart >= 0) {
+ mText.setPaddingRelative(paddingStart, mText.getPaddingTop(), mText.getPaddingEnd(),
+ mText.getPaddingBottom());
+ }
+ }
+
+ void onBindViewHolder(PreferenceViewHolder holder) {
+ mIcon = holder.findViewById(R.id.icon_frame);
+ mText = holder.findViewById(R.id.text_frame);
+ setIconVisible(mIconVisible);
+ setIconPaddingStart(mIconPaddingStart);
+ setTextPaddingStart(mTextPaddingStart);
+ }
+}
diff --git a/src/com/android/settings/widget/RestrictedHomepagePreference.java b/src/com/android/settings/widget/RestrictedHomepagePreference.java
index 4667e2ce314..fbd6d4af097 100644
--- a/src/com/android/settings/widget/RestrictedHomepagePreference.java
+++ b/src/com/android/settings/widget/RestrictedHomepagePreference.java
@@ -19,29 +19,45 @@ package com.android.settings.widget;
import android.content.Context;
import android.util.AttributeSet;
-import com.android.settings.R;
+import androidx.preference.PreferenceViewHolder;
+
import com.android.settingslib.RestrictedTopLevelPreference;
/** Homepage preference that can be disabled by a device admin using a user restriction. */
-public class RestrictedHomepagePreference extends RestrictedTopLevelPreference {
+public class RestrictedHomepagePreference extends RestrictedTopLevelPreference implements
+ HomepagePreferenceLayoutHelper.HomepagePreferenceLayout {
+
+ private final HomepagePreferenceLayoutHelper mHelper;
+
public RestrictedHomepagePreference(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- setLayoutResource(R.layout.homepage_preference);
+ mHelper = new HomepagePreferenceLayoutHelper(this);
}
public RestrictedHomepagePreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- setLayoutResource(R.layout.homepage_preference);
+ mHelper = new HomepagePreferenceLayoutHelper(this);
}
public RestrictedHomepagePreference(Context context, AttributeSet attrs) {
super(context, attrs);
- setLayoutResource(R.layout.homepage_preference);
+ mHelper = new HomepagePreferenceLayoutHelper(this);
}
public RestrictedHomepagePreference(Context context) {
super(context);
- setLayoutResource(R.layout.homepage_preference);
+ mHelper = new HomepagePreferenceLayoutHelper(this);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+ mHelper.onBindViewHolder(holder);
+ }
+
+ @Override
+ public HomepagePreferenceLayoutHelper getHelper() {
+ return mHelper;
}
}
diff --git a/tests/robotests/src/com/android/settings/homepage/TopLevelSettingsTest.java b/tests/robotests/src/com/android/settings/homepage/TopLevelSettingsTest.java
index da2f8b5e566..44f44aa8589 100644
--- a/tests/robotests/src/com/android/settings/homepage/TopLevelSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/TopLevelSettingsTest.java
@@ -30,6 +30,7 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle;
import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
@@ -73,6 +74,7 @@ public class TopLevelSettingsTest {
doReturn(1).when(screen).getPreferenceCount();
doReturn(preference).when(screen).getPreference(anyInt());
doReturn(screen).when(mSettings).getPreferenceScreen();
+ doReturn(new PreferenceManager(mContext)).when(mSettings).getPreferenceManager();
doReturn(0).when(mSettings).getPreferenceScreenResId();
mSettings.onCreatePreferences(new Bundle(), "rootKey");