Refine layouts for large screen
- Support dynamic paddings depending on app's screen width - Add round corners to homepage ripple effect to improve the transition of being highlighted - Add an interface to support dynamic split layout for suggestion cards Bug: 223300824 Test: robotest, manual Change-Id: Iaca6b4fd3f7369179416ef084a800d7eb2ee4640
This commit is contained in:
@@ -14,13 +14,10 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<inset xmlns:android="http://schemas.android.com/apk/res/android"
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:insetLeft="@dimen/homepage_menu_entry_padding_horizontal"
|
android:shape="rectangle">
|
||||||
android:insetRight="@dimen/homepage_menu_entry_padding_horizontal">
|
<solid
|
||||||
<shape android:shape="rectangle">
|
android:color="?android:attr/textColorPrimary" />
|
||||||
<solid
|
<corners
|
||||||
android:color="?android:attr/textColorPrimary" />
|
android:radius="@dimen/homepage_preference_corner_radius" />
|
||||||
<corners
|
</shape>
|
||||||
android:radius="@dimen/homepage_menu_entry_corner_radius" />
|
|
||||||
</shape>
|
|
||||||
</inset>
|
|
27
res/drawable/homepage_selectable_item_background.xml
Normal file
27
res/drawable/homepage_selectable_item_background.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:color="?android:attr/colorControlHighlight">
|
||||||
|
<item android:id="@android:id/mask">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid
|
||||||
|
android:color="@android:color/white" />
|
||||||
|
<corners
|
||||||
|
android:radius="@dimen/homepage_preference_corner_radius" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</ripple>
|
@@ -20,10 +20,8 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minHeight="?android:attr/listPreferredItemHeightSmall"
|
android:minHeight="@dimen/homepage_preference_min_height"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:paddingStart="@dimen/homepage_menu_entry_padding_horizontal"
|
|
||||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:baselineAligned="false">
|
android:baselineAligned="false">
|
||||||
@@ -32,11 +30,10 @@
|
|||||||
android:id="@+id/icon_frame"
|
android:id="@+id/icon_frame"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minWidth="56dp"
|
android:minWidth="48dp"
|
||||||
android:gravity="center"
|
android:gravity="end|center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingStart="8dp"
|
android:paddingStart="@dimen/homepage_preference_icon_padding_start"
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:paddingTop="4dp"
|
android:paddingTop="4dp"
|
||||||
android:paddingBottom="4dp">
|
android:paddingBottom="4dp">
|
||||||
|
|
||||||
@@ -44,18 +41,20 @@
|
|||||||
android:id="@android:id/icon"
|
android:id="@android:id/icon"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:maxWidth="40dp"
|
app:maxWidth="48dp"
|
||||||
app:maxHeight="40dp"/>
|
app:maxHeight="48dp"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
android:id="@+id/text_frame"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:paddingTop="16dp"
|
android:paddingTop="16dp"
|
||||||
android:paddingBottom="16dp"
|
android:paddingBottom="16dp"
|
||||||
android:paddingEnd="16dp">
|
android:paddingStart="@dimen/homepage_preference_text_padding_start"
|
||||||
|
android:paddingEnd="24dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@android:id/title"
|
android:id="@android:id/title"
|
||||||
@@ -78,4 +77,4 @@
|
|||||||
android:maxLines="4"
|
android:maxLines="4"
|
||||||
style="@style/PreferenceSummaryTextStyle"/>
|
style="@style/PreferenceSummaryTextStyle"/>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@@ -31,7 +31,8 @@
|
|||||||
android:id="@+id/search_action_bar"
|
android:id="@+id/search_action_bar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/search_bar_height"
|
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:background="@drawable/search_bar_selected_background"
|
||||||
android:contentInsetStartWithNavigation="@dimen/search_bar_content_inset"
|
android:contentInsetStartWithNavigation="@dimen/search_bar_content_inset"
|
||||||
android:navigationIcon="@drawable/ic_homepage_search">
|
android:navigationIcon="@drawable/ic_homepage_search">
|
||||||
@@ -40,7 +41,7 @@
|
|||||||
style="@style/TextAppearance.SearchBar"
|
style="@style/TextAppearance.SearchBar"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingStart="-4dp"
|
android:paddingStart="@dimen/search_bar_title_padding_start"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
android:text="@string/search_menu"/>
|
android:text="@string/search_menu"/>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
|
@@ -21,20 +21,23 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
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">
|
||||||
<Toolbar
|
<Toolbar
|
||||||
android:id="@+id/search_action_bar_two_pane"
|
android:id="@+id/search_action_bar_two_pane"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/search_bar_height"
|
android:layout_height="@dimen/search_bar_height"
|
||||||
android:paddingStart="4dp"
|
android:paddingStart="@dimen/search_bar_padding_start_two_pane"
|
||||||
|
android:paddingEnd="@dimen/search_bar_padding_end_two_pane"
|
||||||
android:background="@drawable/search_bar_selected_background"
|
android:background="@drawable/search_bar_selected_background"
|
||||||
android:contentInsetStartWithNavigation="@dimen/search_bar_content_inset"
|
android:contentInsetStartWithNavigation="@dimen/search_bar_content_inset"
|
||||||
android:navigationIcon="@drawable/ic_homepage_search">
|
android:navigationIcon="@drawable/ic_homepage_search">
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/search_bar_title"
|
||||||
style="@style/TextAppearance.SearchBar"
|
style="@style/TextAppearance.SearchBar"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingStart="-4dp"
|
android:paddingStart="@dimen/search_bar_title_padding_start_regular_two_pane"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
android:text="@string/search_menu"/>
|
android:text="@string/search_menu"/>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
|
@@ -20,7 +20,6 @@
|
|||||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:background="?androidprv:attr/colorSurface"
|
android:background="?androidprv:attr/colorSurface"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
@@ -41,7 +40,6 @@
|
|||||||
android:layout_width="@dimen/avatar_length"
|
android:layout_width="@dimen/avatar_length"
|
||||||
android:layout_height="@dimen/avatar_length"
|
android:layout_height="@dimen/avatar_length"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:contentDescription="@string/search_bar_account_avatar_content_description"/>
|
android:contentDescription="@string/search_bar_account_avatar_content_description"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@@ -35,9 +35,6 @@
|
|||||||
<!-- SwitchBar sub settings margin start / end -->
|
<!-- SwitchBar sub settings margin start / end -->
|
||||||
<dimen name="switchbar_subsettings_margin_start">80dp</dimen>
|
<dimen name="switchbar_subsettings_margin_start">80dp</dimen>
|
||||||
|
|
||||||
<dimen name="search_bar_height">64dp</dimen>
|
|
||||||
<dimen name="search_bar_half_height">32dp</dimen>
|
|
||||||
|
|
||||||
<!-- Dimensions for Wifi Assistant Card -->
|
<!-- Dimensions for Wifi Assistant Card -->
|
||||||
<dimen name="wifi_assistant_padding_top_bottom">24dp</dimen>
|
<dimen name="wifi_assistant_padding_top_bottom">24dp</dimen>
|
||||||
<dimen name="wifi_assistant_padding_start_end">24dp</dimen>
|
<dimen name="wifi_assistant_padding_start_end">24dp</dimen>
|
||||||
|
@@ -129,6 +129,12 @@
|
|||||||
<dimen name="search_bar_text_size">20sp</dimen>
|
<dimen name="search_bar_text_size">20sp</dimen>
|
||||||
<dimen name="search_bar_corner_radius">28dp</dimen>
|
<dimen name="search_bar_corner_radius">28dp</dimen>
|
||||||
<dimen name="search_bar_content_inset">56dp</dimen>
|
<dimen name="search_bar_content_inset">56dp</dimen>
|
||||||
|
<dimen name="search_bar_padding_start">4dp</dimen>
|
||||||
|
<dimen name="search_bar_padding_start_two_pane">8dp</dimen>
|
||||||
|
<dimen name="search_bar_padding_end">16dp</dimen>
|
||||||
|
<dimen name="search_bar_padding_end_two_pane">24dp</dimen>
|
||||||
|
<dimen name="search_bar_title_padding_start">-4dp</dimen>
|
||||||
|
<dimen name="search_bar_title_padding_start_regular_two_pane">8dp</dimen>
|
||||||
|
|
||||||
<!-- Avatar -->
|
<!-- Avatar -->
|
||||||
<dimen name="avatar_length">48dp</dimen>
|
<dimen name="avatar_length">48dp</dimen>
|
||||||
@@ -136,13 +142,16 @@
|
|||||||
<dimen name="avatar_margin_end">24dp</dimen>
|
<dimen name="avatar_margin_end">24dp</dimen>
|
||||||
<dimen name="multiple_users_avatar_size">20dp</dimen>
|
<dimen name="multiple_users_avatar_size">20dp</dimen>
|
||||||
|
|
||||||
<!-- Homepage title -->
|
<!-- Homepage -->
|
||||||
<dimen name="homepage_title_margin_bottom">8dp</dimen>
|
<dimen name="homepage_title_margin_bottom">8dp</dimen>
|
||||||
<dimen name="homepage_title_margin_horizontal">24dp</dimen>
|
<dimen name="homepage_title_margin_horizontal">24dp</dimen>
|
||||||
|
<dimen name="homepage_padding_horizontal_two_pane">24dp</dimen>
|
||||||
<!-- Homepage menu entry -->
|
<dimen name="homepage_preference_corner_radius">28dp</dimen>
|
||||||
<dimen name="homepage_menu_entry_padding_horizontal">16dp</dimen>
|
<dimen name="homepage_preference_min_height">88sp</dimen>
|
||||||
<dimen name="homepage_menu_entry_corner_radius">28dp</dimen>
|
<dimen name="homepage_preference_icon_padding_start">32dp</dimen>
|
||||||
|
<dimen name="homepage_preference_icon_padding_start_two_pane">8dp</dimen>
|
||||||
|
<dimen name="homepage_preference_text_padding_start">16dp</dimen>
|
||||||
|
<dimen name="homepage_preference_text_padding_start_two_pane">24dp</dimen>
|
||||||
|
|
||||||
<!-- Dimensions for Wifi Assistant Card -->
|
<!-- Dimensions for Wifi Assistant Card -->
|
||||||
<dimen name="wifi_assistant_padding_top_bottom">16dp</dimen>
|
<dimen name="wifi_assistant_padding_top_bottom">16dp</dimen>
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.settings.activityembedding;
|
package com.android.settings.activityembedding;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.FeatureFlagUtils;
|
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 smallest value of the smallest-width (sw) of the window in any rotation when
|
||||||
// the split should be used.
|
// the split should be used.
|
||||||
private static final float MIN_SMALLEST_SCREEN_SPLIT_WIDTH_DP = 600f;
|
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";
|
private static final String TAG = "ActivityEmbeddingUtils";
|
||||||
|
|
||||||
/** Get the smallest pixel value of width of the window when the split should be used. */
|
/** 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;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -86,6 +86,7 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
|
|
||||||
private TopLevelSettings mMainFragment;
|
private TopLevelSettings mMainFragment;
|
||||||
private View mHomepageView;
|
private View mHomepageView;
|
||||||
|
private View mAppBar;
|
||||||
private View mSuggestionView;
|
private View mSuggestionView;
|
||||||
private View mTwoPaneSuggestionView;
|
private View mTwoPaneSuggestionView;
|
||||||
private CategoryMixin mCategoryMixin;
|
private CategoryMixin mCategoryMixin;
|
||||||
@@ -93,6 +94,8 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
private SplitController mSplitController;
|
private SplitController mSplitController;
|
||||||
private boolean mIsEmbeddingActivityEnabled;
|
private boolean mIsEmbeddingActivityEnabled;
|
||||||
private boolean mIsTwoPane;
|
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. */
|
/** A listener receiving homepage loaded events. */
|
||||||
public interface HomepageLoadedListener {
|
public interface HomepageLoadedListener {
|
||||||
@@ -100,8 +103,11 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
void onHomepageLoaded();
|
void onHomepageLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface FragmentBuilder<T extends Fragment> {
|
private interface FragmentCreator<T extends Fragment> {
|
||||||
T build();
|
T create();
|
||||||
|
|
||||||
|
/** To initialize after {@link #create} */
|
||||||
|
default void init(Fragment fragment) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,6 +151,11 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
return mMainFragment;
|
return mMainFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Whether the activity is showing in two-pane */
|
||||||
|
public boolean isTwoPane() {
|
||||||
|
return mIsTwoPane;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CategoryMixin getCategoryMixin() {
|
public CategoryMixin getCategoryMixin() {
|
||||||
return mCategoryMixin;
|
return mCategoryMixin;
|
||||||
@@ -160,8 +171,8 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
mSplitController = SplitController.getInstance();
|
mSplitController = SplitController.getInstance();
|
||||||
mIsTwoPane = mSplitController.isActivityEmbedded(this);
|
mIsTwoPane = mSplitController.isActivityEmbedded(this);
|
||||||
|
|
||||||
final View appBar = findViewById(R.id.app_bar_container);
|
mAppBar = findViewById(R.id.app_bar_container);
|
||||||
appBar.setMinimumHeight(getSearchBoxHeight());
|
mAppBar.setMinimumHeight(getSearchBoxHeight());
|
||||||
initHomepageContainer();
|
initHomepageContainer();
|
||||||
updateHomepageAppBar();
|
updateHomepageAppBar();
|
||||||
updateHomepageBackground();
|
updateHomepageBackground();
|
||||||
@@ -195,6 +206,8 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
|
|
||||||
// Launch the intent from deep link for large screen devices.
|
// Launch the intent from deep link for large screen devices.
|
||||||
launchDeepLinkIntentToRight();
|
launchDeepLinkIntentToRight();
|
||||||
|
updateHomepagePaddings();
|
||||||
|
updateSplitLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -226,7 +239,42 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
mIsTwoPane = newTwoPaneState;
|
mIsTwoPane = newTwoPaneState;
|
||||||
updateHomepageAppBar();
|
updateHomepageAppBar();
|
||||||
updateHomepageBackground();
|
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() {
|
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.
|
// Schedule a timer to show the homepage and hide the suggestion on timeout.
|
||||||
mHomepageView.postDelayed(() -> showHomepageWithSuggestion(false),
|
mHomepageView.postDelayed(() -> showHomepageWithSuggestion(false),
|
||||||
HOMEPAGE_LOADING_TIMEOUT_MS);
|
HOMEPAGE_LOADING_TIMEOUT_MS);
|
||||||
final FragmentBuilder<?> fragmentBuilder = () -> {
|
showFragment(new SuggestionFragCreator(fragmentClass, /* isTwoPaneLayout= */ false),
|
||||||
try {
|
R.id.suggestion_content);
|
||||||
return fragmentClass.getConstructor().newInstance();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.w(TAG, "Cannot show fragment", e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
showFragment(fragmentBuilder, R.id.suggestion_content);
|
|
||||||
if (mIsEmbeddingActivityEnabled) {
|
if (mIsEmbeddingActivityEnabled) {
|
||||||
showFragment(fragmentBuilder, R.id.two_pane_suggestion_content);
|
showFragment(new SuggestionFragCreator(fragmentClass, /* isTwoPaneLayout= */ true),
|
||||||
|
R.id.two_pane_suggestion_content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends Fragment> T showFragment(FragmentBuilder<T> fragmentBuilder, int id) {
|
private <T extends Fragment> T showFragment(FragmentCreator<T> fragmentCreator, int id) {
|
||||||
final FragmentManager fragmentManager = getSupportFragmentManager();
|
final FragmentManager fragmentManager = getSupportFragmentManager();
|
||||||
final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||||
T showFragment = (T) fragmentManager.findFragmentById(id);
|
T showFragment = (T) fragmentManager.findFragmentById(id);
|
||||||
|
|
||||||
if (showFragment == null) {
|
if (showFragment == null) {
|
||||||
showFragment = fragmentBuilder.build();
|
showFragment = fragmentCreator.create();
|
||||||
|
fragmentCreator.init(showFragment);
|
||||||
fragmentTransaction.add(id, showFragment);
|
fragmentTransaction.add(id, showFragment);
|
||||||
} else {
|
} else {
|
||||||
|
fragmentCreator.init(showFragment);
|
||||||
fragmentTransaction.show(showFragment);
|
fragmentTransaction.show(showFragment);
|
||||||
}
|
}
|
||||||
fragmentTransaction.commit();
|
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() {
|
private int getSearchBoxHeight() {
|
||||||
final int searchBarHeight = getResources().getDimensionPixelSize(R.dimen.search_bar_height);
|
final int searchBarHeight = getResources().getDimensionPixelSize(R.dimen.search_bar_height);
|
||||||
final int searchBarMargin = getResources().getDimensionPixelSize(R.dimen.search_bar_margin);
|
final int searchBarMargin = getResources().getDimensionPixelSize(R.dimen.search_bar_margin);
|
||||||
return searchBarHeight + searchBarMargin * 2;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
34
src/com/android/settings/homepage/SplitLayoutListener.java
Normal file
34
src/com/android/settings/homepage/SplitLayoutListener.java
Normal file
@@ -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) {
|
||||||
|
}
|
||||||
|
}
|
@@ -27,6 +27,8 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
@@ -44,12 +46,13 @@ import com.android.settings.dashboard.DashboardFragment;
|
|||||||
import com.android.settings.search.BaseSearchIndexProvider;
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
import com.android.settings.support.SupportPreferenceController;
|
import com.android.settings.support.SupportPreferenceController;
|
||||||
import com.android.settings.widget.HomepagePreference;
|
import com.android.settings.widget.HomepagePreference;
|
||||||
|
import com.android.settings.widget.HomepagePreferenceLayoutHelper.HomepagePreferenceLayout;
|
||||||
import com.android.settingslib.core.instrumentation.Instrumentable;
|
import com.android.settingslib.core.instrumentation.Instrumentable;
|
||||||
import com.android.settingslib.drawer.Tile;
|
import com.android.settingslib.drawer.Tile;
|
||||||
import com.android.settingslib.search.SearchIndexable;
|
import com.android.settingslib.search.SearchIndexable;
|
||||||
|
|
||||||
@SearchIndexable(forTarget = MOBILE)
|
@SearchIndexable(forTarget = MOBILE)
|
||||||
public class TopLevelSettings extends DashboardFragment implements
|
public class TopLevelSettings extends DashboardFragment implements SplitLayoutListener,
|
||||||
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
|
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
|
||||||
|
|
||||||
private static final String TAG = "TopLevelSettings";
|
private static final String TAG = "TopLevelSettings";
|
||||||
@@ -58,6 +61,7 @@ public class TopLevelSettings extends DashboardFragment implements
|
|||||||
|
|
||||||
private boolean mIsEmbeddingActivityEnabled;
|
private boolean mIsEmbeddingActivityEnabled;
|
||||||
private TopLevelHighlightMixin mHighlightMixin;
|
private TopLevelHighlightMixin mHighlightMixin;
|
||||||
|
private int mPaddingHorizontal;
|
||||||
private boolean mScrollNeeded = true;
|
private boolean mScrollNeeded = true;
|
||||||
private boolean mFirstStarted = true;
|
private boolean mFirstStarted = true;
|
||||||
|
|
||||||
@@ -177,23 +181,13 @@ public class TopLevelSettings extends DashboardFragment implements
|
|||||||
@Override
|
@Override
|
||||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||||
super.onCreatePreferences(savedInstanceState, rootKey);
|
super.onCreatePreferences(savedInstanceState, rootKey);
|
||||||
final PreferenceScreen screen = getPreferenceScreen();
|
int tintColor = Utils.getHomepageIconColor(getContext());
|
||||||
if (screen == null) {
|
iteratePreferences(preference -> {
|
||||||
return;
|
Drawable icon = preference.getIcon();
|
||||||
}
|
|
||||||
// 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();
|
|
||||||
if (icon != null) {
|
if (icon != null) {
|
||||||
icon.setTint(tintColor);
|
icon.setTint(tintColor);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -202,6 +196,15 @@ public class TopLevelSettings extends DashboardFragment implements
|
|||||||
highlightPreferenceIfNeeded();
|
highlightPreferenceIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSplitLayoutChanged(boolean isRegularLayout) {
|
||||||
|
iteratePreferences(preference -> {
|
||||||
|
if (preference instanceof HomepagePreferenceLayout) {
|
||||||
|
((HomepagePreferenceLayout) preference).getHelper().setIconVisible(isRegularLayout);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void highlightPreferenceIfNeeded() {
|
public void highlightPreferenceIfNeeded() {
|
||||||
if (mHighlightMixin != null) {
|
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 */
|
/** Returns a {@link TopLevelHighlightMixin} that performs highlighting */
|
||||||
public TopLevelHighlightMixin getHighlightMixin() {
|
public TopLevelHighlightMixin getHighlightMixin() {
|
||||||
return mHighlightMixin;
|
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 =
|
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||||
new BaseSearchIndexProvider(R.xml.top_level_settings) {
|
new BaseSearchIndexProvider(R.xml.top_level_settings) {
|
||||||
|
|
||||||
|
@@ -21,7 +21,6 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -46,6 +45,10 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
|
|||||||
private static final String TAG = "HighlightableTopLevelAdapter";
|
private static final String TAG = "HighlightableTopLevelAdapter";
|
||||||
|
|
||||||
static final long DELAY_HIGHLIGHT_DURATION_MILLIS = 100L;
|
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 mTitleColorNormal;
|
||||||
private final int mTitleColorHighlight;
|
private final int mTitleColorHighlight;
|
||||||
@@ -54,11 +57,8 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
|
|||||||
private final int mIconColorNormal;
|
private final int mIconColorNormal;
|
||||||
private final int mIconColorHighlight;
|
private final int mIconColorHighlight;
|
||||||
|
|
||||||
private final Context mContext;
|
|
||||||
private final SettingsHomepageActivity mHomepageActivity;
|
private final SettingsHomepageActivity mHomepageActivity;
|
||||||
private final RecyclerView mRecyclerView;
|
private final RecyclerView mRecyclerView;
|
||||||
private final int mNormalBackgroundRes;
|
|
||||||
private final int mHighlightBackgroundRes;
|
|
||||||
private String mHighlightKey;
|
private String mHighlightKey;
|
||||||
private int mHighlightPosition = RecyclerView.NO_POSITION;
|
private int mHighlightPosition = RecyclerView.NO_POSITION;
|
||||||
private int mScrollPosition = RecyclerView.NO_POSITION;
|
private int mScrollPosition = RecyclerView.NO_POSITION;
|
||||||
@@ -74,23 +74,18 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
|
|||||||
mHighlightKey = key;
|
mHighlightKey = key;
|
||||||
mScrolled = !scrollNeeded;
|
mScrolled = !scrollNeeded;
|
||||||
mViewHolders = new SparseArray<>();
|
mViewHolders = new SparseArray<>();
|
||||||
mContext = preferenceGroup.getContext();
|
|
||||||
mHomepageActivity = homepageActivity;
|
mHomepageActivity = homepageActivity;
|
||||||
final TypedValue outValue = new TypedValue();
|
Context context = preferenceGroup.getContext();
|
||||||
mContext.getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
|
mTitleColorNormal = Utils.getColorAttrDefaultColor(context,
|
||||||
outValue, true /* resolveRefs */);
|
|
||||||
mNormalBackgroundRes = outValue.resourceId;
|
|
||||||
mHighlightBackgroundRes = R.drawable.homepage_highlighted_item_background;
|
|
||||||
mTitleColorNormal = Utils.getColorAttrDefaultColor(mContext,
|
|
||||||
android.R.attr.textColorPrimary);
|
android.R.attr.textColorPrimary);
|
||||||
mTitleColorHighlight = Utils.getColorAttrDefaultColor(mContext,
|
mTitleColorHighlight = Utils.getColorAttrDefaultColor(context,
|
||||||
android.R.attr.textColorPrimaryInverse);
|
android.R.attr.textColorPrimaryInverse);
|
||||||
mSummaryColorNormal = Utils.getColorAttrDefaultColor(mContext,
|
mSummaryColorNormal = Utils.getColorAttrDefaultColor(context,
|
||||||
android.R.attr.textColorSecondary);
|
android.R.attr.textColorSecondary);
|
||||||
mSummaryColorHighlight = Utils.getColorAttrDefaultColor(mContext,
|
mSummaryColorHighlight = Utils.getColorAttrDefaultColor(context,
|
||||||
android.R.attr.textColorSecondaryInverse);
|
android.R.attr.textColorSecondaryInverse);
|
||||||
mIconColorNormal = Utils.getHomepageIconColor(mContext);
|
mIconColorNormal = Utils.getHomepageIconColor(context);
|
||||||
mIconColorHighlight = Utils.getHomepageIconColorHighlight(mContext);
|
mIconColorHighlight = Utils.getHomepageIconColorHighlight(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -236,7 +231,7 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
|
|||||||
|
|
||||||
private void addHighlightBackground(PreferenceViewHolder holder) {
|
private void addHighlightBackground(PreferenceViewHolder holder) {
|
||||||
final View v = holder.itemView;
|
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.title)).setTextColor(mTitleColorHighlight);
|
||||||
((TextView) v.findViewById(android.R.id.summary)).setTextColor(mSummaryColorHighlight);
|
((TextView) v.findViewById(android.R.id.summary)).setTextColor(mSummaryColorHighlight);
|
||||||
final Drawable drawable = ((ImageView) v.findViewById(android.R.id.icon)).getDrawable();
|
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) {
|
private void removeHighlightBackground(PreferenceViewHolder holder) {
|
||||||
final View v = holder.itemView;
|
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.title)).setTextColor(mTitleColorNormal);
|
||||||
((TextView) v.findViewById(android.R.id.summary)).setTextColor(mSummaryColorNormal);
|
((TextView) v.findViewById(android.R.id.summary)).setTextColor(mSummaryColorNormal);
|
||||||
final Drawable drawable = ((ImageView) v.findViewById(android.R.id.icon)).getDrawable();
|
final Drawable drawable = ((ImageView) v.findViewById(android.R.id.icon)).getDrawable();
|
||||||
|
@@ -20,29 +20,43 @@ import android.content.Context;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceViewHolder;
|
||||||
import com.android.settings.R;
|
|
||||||
|
|
||||||
/** A customized layout for homepage preference. */
|
/** 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,
|
public HomepagePreference(Context context, AttributeSet attrs, int defStyleAttr,
|
||||||
int defStyleRes) {
|
int defStyleRes) {
|
||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
setLayoutResource(R.layout.homepage_preference);
|
mHelper = new HomepagePreferenceLayoutHelper(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HomepagePreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
public HomepagePreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
setLayoutResource(R.layout.homepage_preference);
|
mHelper = new HomepagePreferenceLayoutHelper(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HomepagePreference(Context context, AttributeSet attrs) {
|
public HomepagePreference(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
setLayoutResource(R.layout.homepage_preference);
|
mHelper = new HomepagePreferenceLayoutHelper(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HomepagePreference(Context context) {
|
public HomepagePreference(Context context) {
|
||||||
super(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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
@@ -19,29 +19,45 @@ package com.android.settings.widget;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import androidx.preference.PreferenceViewHolder;
|
||||||
|
|
||||||
import com.android.settingslib.RestrictedTopLevelPreference;
|
import com.android.settingslib.RestrictedTopLevelPreference;
|
||||||
|
|
||||||
/** Homepage preference that can be disabled by a device admin using a user restriction. */
|
/** 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,
|
public RestrictedHomepagePreference(Context context, AttributeSet attrs, int defStyleAttr,
|
||||||
int defStyleRes) {
|
int defStyleRes) {
|
||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
setLayoutResource(R.layout.homepage_preference);
|
mHelper = new HomepagePreferenceLayoutHelper(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RestrictedHomepagePreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
public RestrictedHomepagePreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
setLayoutResource(R.layout.homepage_preference);
|
mHelper = new HomepagePreferenceLayoutHelper(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RestrictedHomepagePreference(Context context, AttributeSet attrs) {
|
public RestrictedHomepagePreference(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
setLayoutResource(R.layout.homepage_preference);
|
mHelper = new HomepagePreferenceLayoutHelper(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RestrictedHomepagePreference(Context context) {
|
public RestrictedHomepagePreference(Context context) {
|
||||||
super(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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,7 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceManager;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
@@ -73,6 +74,7 @@ public class TopLevelSettingsTest {
|
|||||||
doReturn(1).when(screen).getPreferenceCount();
|
doReturn(1).when(screen).getPreferenceCount();
|
||||||
doReturn(preference).when(screen).getPreference(anyInt());
|
doReturn(preference).when(screen).getPreference(anyInt());
|
||||||
doReturn(screen).when(mSettings).getPreferenceScreen();
|
doReturn(screen).when(mSettings).getPreferenceScreen();
|
||||||
|
doReturn(new PreferenceManager(mContext)).when(mSettings).getPreferenceManager();
|
||||||
doReturn(0).when(mSettings).getPreferenceScreenResId();
|
doReturn(0).when(mSettings).getPreferenceScreenResId();
|
||||||
|
|
||||||
mSettings.onCreatePreferences(new Bundle(), "rootKey");
|
mSettings.onCreatePreferences(new Bundle(), "rootKey");
|
||||||
|
Reference in New Issue
Block a user