Homepage UX revamp
- unified Search and Suggestion behavior between regular phone and two pane - don't adjust padding - update new icon drawable - support group homepage preference with round corner on phone - Remove avator from homepage - Adjust homepage preference order Bug: 333989622 Bug: 334130370 Test: visual Change-Id: I9880b52553f164745766c8b9d5c996585285e52a
This commit is contained in:
151
src/com/android/settings/core/RoundCornerPreferenceAdapter.java
Normal file
151
src/com/android/settings/core/RoundCornerPreferenceAdapter.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.core;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceGroup;
|
||||
import androidx.preference.PreferenceGroupAdapter;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settingslib.widget.theme.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RoundCornerPreferenceAdapter extends PreferenceGroupAdapter {
|
||||
|
||||
private static final int ROUND_CORNER_CENTER = 1;
|
||||
private static final int ROUND_CORNER_TOP = 1 << 1;
|
||||
private static final int ROUND_CORNER_BOTTOM = 1 << 2;
|
||||
|
||||
private final PreferenceGroup mPreferenceGroup;
|
||||
|
||||
private List<Integer> mRoundCornerMappingList;
|
||||
|
||||
private final Handler mHandler;
|
||||
|
||||
private final Runnable mSyncRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updatePreferences();
|
||||
}
|
||||
};
|
||||
|
||||
public RoundCornerPreferenceAdapter(@NonNull PreferenceGroup preferenceGroup) {
|
||||
super(preferenceGroup);
|
||||
mPreferenceGroup = preferenceGroup;
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
updatePreferences();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreferenceHierarchyChange(@NonNull Preference preference) {
|
||||
super.onPreferenceHierarchyChange(preference);
|
||||
mHandler.removeCallbacks(mSyncRunnable);
|
||||
mHandler.post(mSyncRunnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull PreferenceViewHolder holder, int position) {
|
||||
super.onBindViewHolder(holder, position);
|
||||
updateBackground(holder, position);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess") /* synthetic access */
|
||||
private void updatePreferences() {
|
||||
mRoundCornerMappingList = new ArrayList<>();
|
||||
mappingPreferenceGroup(mRoundCornerMappingList, mPreferenceGroup);
|
||||
}
|
||||
private void mappingPreferenceGroup(List<Integer> visibleList, PreferenceGroup group) {
|
||||
int groupSize = group.getPreferenceCount();
|
||||
int firstVisible = 0;
|
||||
int lastVisible = 0;
|
||||
for (int i = 0; i < groupSize; i++) {
|
||||
Preference pref = group.getPreference(i);
|
||||
if (!pref.isVisible()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//the first visible preference.
|
||||
Preference firstVisiblePref = group.getPreference(firstVisible);
|
||||
if (!firstVisiblePref.isVisible()) {
|
||||
firstVisible = i;
|
||||
}
|
||||
|
||||
int value = 0;
|
||||
if (group instanceof PreferenceCategory) {
|
||||
if (pref instanceof PreferenceCategory) {
|
||||
visibleList.add(value);
|
||||
mappingPreferenceGroup(visibleList, (PreferenceCategory) pref);
|
||||
} else {
|
||||
if (i == firstVisible) {
|
||||
value |= ROUND_CORNER_TOP;
|
||||
}
|
||||
|
||||
value |= ROUND_CORNER_BOTTOM;
|
||||
if (i > lastVisible) {
|
||||
// the last
|
||||
int lastIndex = visibleList.size() - 1;
|
||||
int newValue = visibleList.get(lastIndex) & ~ROUND_CORNER_BOTTOM;
|
||||
visibleList.set(lastIndex, newValue);
|
||||
lastVisible = i;
|
||||
}
|
||||
|
||||
value |= ROUND_CORNER_CENTER;
|
||||
visibleList.add(value);
|
||||
}
|
||||
} else {
|
||||
visibleList.add(value);
|
||||
if (pref instanceof PreferenceCategory) {
|
||||
mappingPreferenceGroup(visibleList, (PreferenceCategory) pref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** handle roundCorner background */
|
||||
private void updateBackground(PreferenceViewHolder holder, int position) {
|
||||
int CornerType = mRoundCornerMappingList.get(position);
|
||||
|
||||
if ((CornerType & ROUND_CORNER_CENTER) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
View v = holder.itemView;
|
||||
if (((CornerType & ROUND_CORNER_TOP) != 0) && ((CornerType & ROUND_CORNER_BOTTOM) == 0)) {
|
||||
// the first
|
||||
v.setBackgroundResource(R.drawable.settingslib_round_background_top);
|
||||
} else if (((CornerType & ROUND_CORNER_BOTTOM) != 0)
|
||||
&& ((CornerType & ROUND_CORNER_TOP) == 0)) {
|
||||
// the last
|
||||
v.setBackgroundResource(R.drawable.settingslib_round_background_bottom);
|
||||
} else if (((CornerType & ROUND_CORNER_TOP) != 0)
|
||||
&& ((CornerType & ROUND_CORNER_BOTTOM) != 0)) {
|
||||
// the only one preference
|
||||
v.setBackgroundResource(R.drawable.settingslib_round_background);
|
||||
} else {
|
||||
// in the center
|
||||
v.setBackgroundResource(R.drawable.settingslib_round_background_center);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -444,7 +444,9 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
|
||||
}
|
||||
if (TextUtils.equals(tile.getCategory(), CategoryKey.CATEGORY_HOMEPAGE)) {
|
||||
iconDrawable.setTint(Utils.getHomepageIconColor(preference.getContext()));
|
||||
} else if (forceRoundedIcon && !TextUtils.equals(mContext.getPackageName(), iconPackage)) {
|
||||
}
|
||||
|
||||
if (forceRoundedIcon && !TextUtils.equals(mContext.getPackageName(), iconPackage)) {
|
||||
iconDrawable = new AdaptiveIcon(mContext, iconDrawable,
|
||||
R.dimen.dashboard_tile_foreground_image_inset);
|
||||
((AdaptiveIcon) iconDrawable).setBackgroundColor(mContext, tile);
|
||||
|
||||
@@ -72,6 +72,7 @@ import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
|
||||
import com.android.settings.activityembedding.ActivityEmbeddingUtils;
|
||||
import com.android.settings.core.CategoryMixin;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.safetycenter.SafetyCenterManagerWrapper;
|
||||
@@ -159,8 +160,12 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
if (mAllowUpdateSuggestion) {
|
||||
Log.i(TAG, "showHomepageWithSuggestion: " + showSuggestion);
|
||||
mAllowUpdateSuggestion = false;
|
||||
mSuggestionView.setVisibility(showSuggestion ? View.VISIBLE : View.GONE);
|
||||
mTwoPaneSuggestionView.setVisibility(showSuggestion ? View.VISIBLE : View.GONE);
|
||||
if (Flags.homepageRevamp()) {
|
||||
mSuggestionView.setVisibility(showSuggestion ? View.VISIBLE : View.GONE);
|
||||
} else {
|
||||
mSuggestionView.setVisibility(showSuggestion ? View.VISIBLE : View.GONE);
|
||||
mTwoPaneSuggestionView.setVisibility(showSuggestion ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (mHomepageView == null) {
|
||||
@@ -244,7 +249,10 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
}
|
||||
|
||||
setupEdgeToEdge();
|
||||
setContentView(R.layout.settings_homepage_container);
|
||||
setContentView(
|
||||
Flags.homepageRevamp()
|
||||
? R.layout.settings_homepage_container_v2
|
||||
: R.layout.settings_homepage_container);
|
||||
|
||||
mIsTwoPane = ActivityEmbeddingUtils.isAlreadyEmbedded(this);
|
||||
|
||||
@@ -396,19 +404,31 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
}
|
||||
|
||||
private void initSearchBarView() {
|
||||
final Toolbar toolbar = findViewById(R.id.search_action_bar);
|
||||
FeatureFactory.getFeatureFactory().getSearchFeatureProvider()
|
||||
.initSearchToolbar(this /* activity */, toolbar, SettingsEnums.SETTINGS_HOMEPAGE);
|
||||
|
||||
if (mIsEmbeddingActivityEnabled) {
|
||||
final Toolbar toolbarTwoPaneVersion = findViewById(R.id.search_action_bar_two_pane);
|
||||
if (Flags.homepageRevamp()) {
|
||||
Toolbar toolbar = findViewById(R.id.search_action_bar_unified);
|
||||
FeatureFactory.getFeatureFactory().getSearchFeatureProvider()
|
||||
.initSearchToolbar(this /* activity */, toolbarTwoPaneVersion,
|
||||
.initSearchToolbar(this /* activity */, toolbar,
|
||||
SettingsEnums.SETTINGS_HOMEPAGE);
|
||||
} else {
|
||||
final Toolbar toolbar = findViewById(R.id.search_action_bar);
|
||||
FeatureFactory.getFeatureFactory().getSearchFeatureProvider()
|
||||
.initSearchToolbar(this /* activity */, toolbar,
|
||||
SettingsEnums.SETTINGS_HOMEPAGE);
|
||||
|
||||
if (mIsEmbeddingActivityEnabled) {
|
||||
final Toolbar toolbarTwoPaneVersion = findViewById(R.id.search_action_bar_two_pane);
|
||||
FeatureFactory.getFeatureFactory().getSearchFeatureProvider()
|
||||
.initSearchToolbar(this /* activity */, toolbarTwoPaneVersion,
|
||||
SettingsEnums.SETTINGS_HOMEPAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initAvatarView() {
|
||||
if (Flags.homepageRevamp()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ImageView avatarView = findViewById(R.id.account_avatar);
|
||||
final ImageView avatarTwoPaneView = findViewById(R.id.account_avatar_two_pane_version);
|
||||
if (AvatarViewMixin.isAvatarSupported(this)) {
|
||||
@@ -457,8 +477,12 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
return;
|
||||
}
|
||||
|
||||
mSuggestionView = findViewById(R.id.suggestion_content);
|
||||
mTwoPaneSuggestionView = findViewById(R.id.two_pane_suggestion_content);
|
||||
if (Flags.homepageRevamp()) {
|
||||
mSuggestionView = findViewById(R.id.unified_suggestion_content);
|
||||
} else {
|
||||
mSuggestionView = findViewById(R.id.suggestion_content);
|
||||
mTwoPaneSuggestionView = findViewById(R.id.two_pane_suggestion_content);
|
||||
}
|
||||
mHomepageView = findViewById(R.id.settings_homepage_container);
|
||||
// Hide the homepage for preparing the suggestion. If scrolling is needed, the list views
|
||||
// should be initialized in the invisible homepage view to prevent a scroll flicker.
|
||||
@@ -466,11 +490,16 @@ 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);
|
||||
showFragment(new SuggestionFragCreator(fragmentClass, /* isTwoPaneLayout= */ false),
|
||||
R.id.suggestion_content);
|
||||
if (mIsEmbeddingActivityEnabled) {
|
||||
showFragment(new SuggestionFragCreator(fragmentClass, /* isTwoPaneLayout= */ true),
|
||||
R.id.two_pane_suggestion_content);
|
||||
if (Flags.homepageRevamp()) {
|
||||
showFragment(new SuggestionFragCreator(fragmentClass, true),
|
||||
R.id.unified_suggestion_content);
|
||||
} else {
|
||||
showFragment(new SuggestionFragCreator(fragmentClass, /* isTwoPaneLayout= */ false),
|
||||
R.id.suggestion_content);
|
||||
if (mIsEmbeddingActivityEnabled) {
|
||||
showFragment(new SuggestionFragCreator(fragmentClass, /* isTwoPaneLayout= */ true),
|
||||
R.id.two_pane_suggestion_content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -735,7 +764,7 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
}
|
||||
|
||||
private void updateHomepageAppBar() {
|
||||
if (!mIsEmbeddingActivityEnabled) {
|
||||
if (Flags.homepageRevamp() || !mIsEmbeddingActivityEnabled) {
|
||||
return;
|
||||
}
|
||||
updateAppBarMinHeight();
|
||||
@@ -751,7 +780,7 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
}
|
||||
|
||||
private void updateHomepagePaddings() {
|
||||
if (!mIsEmbeddingActivityEnabled) {
|
||||
if (Flags.homepageRevamp() || !mIsEmbeddingActivityEnabled) {
|
||||
return;
|
||||
}
|
||||
if (mIsTwoPane) {
|
||||
@@ -765,6 +794,9 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
||||
}
|
||||
|
||||
private void updateAppBarMinHeight() {
|
||||
if (Flags.homepageRevamp()) {
|
||||
return;
|
||||
}
|
||||
final int searchBarHeight = getResources().getDimensionPixelSize(R.dimen.search_bar_height);
|
||||
final int margin = getResources().getDimensionPixelSize(
|
||||
mIsEmbeddingActivityEnabled && mIsTwoPane
|
||||
|
||||
@@ -42,8 +42,10 @@ import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
|
||||
import com.android.settings.activityembedding.ActivityEmbeddingUtils;
|
||||
import com.android.settings.core.RoundCornerPreferenceAdapter;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.support.SupportPreferenceController;
|
||||
@@ -84,7 +86,7 @@ public class TopLevelSettings extends DashboardFragment implements SplitLayoutLi
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.top_level_settings;
|
||||
return Flags.homepageRevamp() ? R.xml.top_level_settings_v2 : R.xml.top_level_settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -331,10 +333,14 @@ public class TopLevelSettings extends DashboardFragment implements SplitLayoutLi
|
||||
|
||||
@Override
|
||||
protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {
|
||||
if (!mIsEmbeddingActivityEnabled || !(getActivity() instanceof SettingsHomepageActivity)) {
|
||||
return super.onCreateAdapter(preferenceScreen);
|
||||
if (mIsEmbeddingActivityEnabled && (getActivity() instanceof SettingsHomepageActivity)) {
|
||||
return mHighlightMixin.onCreateAdapter(this, preferenceScreen, mScrollNeeded);
|
||||
}
|
||||
return mHighlightMixin.onCreateAdapter(this, preferenceScreen, mScrollNeeded);
|
||||
|
||||
if (Flags.homepageRevamp()) {
|
||||
return new RoundCornerPreferenceAdapter(preferenceScreen);
|
||||
}
|
||||
return super.onCreateAdapter(preferenceScreen);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -376,7 +382,10 @@ public class TopLevelSettings extends DashboardFragment implements SplitLayoutLi
|
||||
}
|
||||
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider(R.xml.top_level_settings) {
|
||||
new BaseSearchIndexProvider(
|
||||
Flags.homepageRevamp()
|
||||
? R.xml.top_level_settings_v2
|
||||
: R.xml.top_level_settings) {
|
||||
|
||||
@Override
|
||||
protected boolean isPageSearchEnabled(Context context) {
|
||||
|
||||
@@ -34,6 +34,7 @@ import androidx.window.embedding.ActivityEmbeddingController;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.homepage.SettingsHomepageActivity;
|
||||
|
||||
/**
|
||||
@@ -46,9 +47,13 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
|
||||
|
||||
static final long DELAY_HIGHLIGHT_DURATION_MILLIS = 100L;
|
||||
private static final int RES_NORMAL_BACKGROUND =
|
||||
R.drawable.homepage_selectable_item_background;
|
||||
Flags.homepageRevamp()
|
||||
? R.drawable.homepage_selectable_item_background_v2
|
||||
: R.drawable.homepage_selectable_item_background;
|
||||
private static final int RES_HIGHLIGHTED_BACKGROUND =
|
||||
R.drawable.homepage_highlighted_item_background;
|
||||
Flags.homepageRevamp()
|
||||
? R.drawable.homepage_highlighted_item_background_v2
|
||||
: R.drawable.homepage_highlighted_item_background;
|
||||
|
||||
private final int mTitleColorNormal;
|
||||
private final int mTitleColorHighlight;
|
||||
|
||||
@@ -22,6 +22,7 @@ import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.flags.Flags;
|
||||
|
||||
/** Helper for homepage preference to manage layout. */
|
||||
public class HomepagePreferenceLayoutHelper {
|
||||
@@ -39,7 +40,10 @@ public class HomepagePreferenceLayoutHelper {
|
||||
}
|
||||
|
||||
public HomepagePreferenceLayoutHelper(Preference preference) {
|
||||
preference.setLayoutResource(R.layout.homepage_preference);
|
||||
preference.setLayoutResource(
|
||||
Flags.homepageRevamp()
|
||||
? R.layout.homepage_preference_v2
|
||||
: R.layout.homepage_preference);
|
||||
}
|
||||
|
||||
/** Sets whether the icon should be visible */
|
||||
|
||||
Reference in New Issue
Block a user