diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c946122efc4..2eaebb1173a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -174,7 +174,8 @@ - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/values-night/themes.xml b/res/values-night/themes.xml index c5f67febfa9..a4f495a6507 100644 --- a/res/values-night/themes.xml +++ b/res/values-night/themes.xml @@ -44,4 +44,10 @@ + + diff --git a/res/values/styles.xml b/res/values/styles.xml index ce6b09551a6..4ab1e6c90ec 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -874,4 +874,17 @@ 16sp ?android:attr/textColorSecondary + + + + + + diff --git a/res/values/themes.xml b/res/values/themes.xml index 01ea10302bf..fc692463dfa 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -72,7 +72,7 @@ true - + + diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index 1c2952a3b46..7f214f67e23 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -288,7 +288,9 @@ public class SettingsActivity extends SettingsBaseActivity if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(!isInSetupWizard); actionBar.setHomeButtonEnabled(!isInSetupWizard); - actionBar.setDisplayShowTitleEnabled(true); + // TODO(b/176882938): Enable title after material component updated + // If CollapsingToolbarLayout is applied, the old action bar won't show title. + actionBar.setDisplayShowTitleEnabled(mCollapsingToolbarLayout == null); } mSwitchBar = findViewById(R.id.switch_bar); if (mSwitchBar != null) { diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java index 659ada4bd40..2c628f6f375 100644 --- a/src/com/android/settings/SettingsPreferenceFragment.java +++ b/src/com/android/settings/SettingsPreferenceFragment.java @@ -26,6 +26,7 @@ import android.content.pm.PackageManager; import android.os.Bundle; import android.text.TextUtils; import android.util.ArrayMap; +import android.util.FeatureFlagUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -42,6 +43,7 @@ import androidx.preference.PreferenceScreen; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.android.settings.core.FeatureFlags; import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.search.actionbar.SearchMenuController; @@ -126,8 +128,11 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); - SearchMenuController.init(this /* host */); - HelpMenuController.init(this /* host */); + // TODO(b/176883483): Remove both search and help menu if this feature rolled out + if (!FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.SILKY_HOME)) { + SearchMenuController.init(this /* host */); + HelpMenuController.init(this /* host */); + } if (icicle != null) { mPreferenceHighlighted = icicle.getBoolean(SAVE_HIGHLIGHTED_KEY); diff --git a/src/com/android/settings/core/SettingsBaseActivity.java b/src/com/android/settings/core/SettingsBaseActivity.java index d160dc5e9d5..470470290d0 100644 --- a/src/com/android/settings/core/SettingsBaseActivity.java +++ b/src/com/android/settings/core/SettingsBaseActivity.java @@ -29,6 +29,7 @@ import android.os.AsyncTask; import android.os.Bundle; import android.text.TextUtils; import android.util.ArraySet; +import android.util.FeatureFlagUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -43,8 +44,11 @@ import com.android.settings.SubSettings; import com.android.settings.dashboard.CategoryManager; import com.android.settingslib.drawer.Tile; +import com.google.android.material.appbar.CollapsingToolbarLayout; import com.google.android.setupcompat.util.WizardManagerHelper; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -55,6 +59,7 @@ public class SettingsBaseActivity extends FragmentActivity { protected static final boolean DEBUG_TIMING = false; private static final String TAG = "SettingsBaseActivity"; private static final String DATA_SCHEME_PKG = "package"; + private static final int TOOLBAR_MAX_LINE_NUMBER = 2; // Serves as a temporary list of tiles to ignore until we heard back from the PM that they // are disabled. @@ -62,6 +67,8 @@ public class SettingsBaseActivity extends FragmentActivity { private final PackageReceiver mPackageReceiver = new PackageReceiver(); private final List mCategoryListeners = new ArrayList<>(); + + protected CollapsingToolbarLayout mCollapsingToolbarLayout; private int mCategoriesUpdateTaskCount; @Override @@ -79,21 +86,30 @@ public class SettingsBaseActivity extends FragmentActivity { requestWindowFeature(Window.FEATURE_NO_TITLE); } // Apply SetupWizard light theme during setup flow. This is for SubSettings pages. - if (WizardManagerHelper.isAnySetupWizard(getIntent()) && this instanceof SubSettings) { + final boolean isAnySetupWizard = WizardManagerHelper.isAnySetupWizard(getIntent()); + if (isAnySetupWizard && this instanceof SubSettings) { setTheme(R.style.LightTheme_SubSettings_SetupWizard); } - super.setContentView(R.layout.settings_base_layout); + if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SILKY_HOME) + && isToolbarEnabled() && !isAnySetupWizard) { + super.setContentView(R.layout.settings_collapsing_base_layout); + mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar); + } else { + super.setContentView(R.layout.settings_base_layout); + } + + // This is to hide the toolbar from those pages which don't need a toolbar originally. final Toolbar toolbar = findViewById(R.id.action_bar); - if (theme.getBoolean(android.R.styleable.Theme_windowNoTitle, false)) { + if (!isToolbarEnabled() || isAnySetupWizard) { toolbar.setVisibility(View.GONE); return; } setActionBar(toolbar); + initCollapsingToolbar(); if (DEBUG_TIMING) { - Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime) - + " ms"); + Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime) + " ms"); } } @@ -151,6 +167,70 @@ public class SettingsBaseActivity extends FragmentActivity { ((ViewGroup) findViewById(R.id.content_frame)).addView(view, params); } + @Override + public void setTitle(CharSequence title) { + if (mCollapsingToolbarLayout != null) { + mCollapsingToolbarLayout.setTitle(title); + } + super.setTitle(title); + } + + @Override + public void setTitle(int titleId) { + if (mCollapsingToolbarLayout != null) { + mCollapsingToolbarLayout.setTitle(getText(titleId)); + } + super.setTitle(titleId); + } + + /** + * SubSetting page should show a toolbar by default. If the page wouldn't show a toolbar, + * override this method and return false value. + * @return ture by default + */ + protected boolean isToolbarEnabled() { + return true; + } + + private void initCollapsingToolbar() { + if (mCollapsingToolbarLayout == null) { + return; + } + mCollapsingToolbarLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + v.removeOnLayoutChangeListener(this); + final int count = getLineCount(); + if (count > TOOLBAR_MAX_LINE_NUMBER) { + mCollapsingToolbarLayout + .setExpandedTitleTextAppearance(R.style.ToolbarText_MoreThanTwoLines); + } else { + mCollapsingToolbarLayout.setExpandedTitleTextAppearance(R.style.ToolbarText); + } + } + }); + } + + private int getLineCount() { + try { + final Class toolbarClazz = mCollapsingToolbarLayout.getClass(); + final Field textHelperField = toolbarClazz.getDeclaredField("collapsingTextHelper"); + textHelperField.setAccessible(true); + final Object textHelperObj = textHelperField.get(mCollapsingToolbarLayout); + + final Field layoutField = textHelperObj.getClass().getDeclaredField("textLayout"); + layoutField.setAccessible(true); + final Object layoutObj = layoutField.get(textHelperObj); + + final Method method = layoutObj.getClass().getDeclaredMethod("getLineCount"); + return (int) method.invoke(layoutObj); + } catch (Exception e) { + return 0; + } + } + + private void onCategoriesChanged(Set categories) { final int N = mCategoryListeners.size(); for (int i = 0; i < N; i++) { diff --git a/src/com/android/settings/network/telephony/MobileNetworkActivity.java b/src/com/android/settings/network/telephony/MobileNetworkActivity.java index b179770d485..92f0054d2e7 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkActivity.java +++ b/src/com/android/settings/network/telephony/MobileNetworkActivity.java @@ -115,6 +115,9 @@ public class MobileNetworkActivity extends SettingsBaseActivity final ActionBar actionBar = getActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); + // TODO(b/176882938): Enable title after material component updated + // If CollapsingToolbarLayout is applied, the old action bar won't show title. + actionBar.setDisplayShowTitleEnabled(mCollapsingToolbarLayout == null); } getProxySubscriptionManager().setLifecycle(getLifecycle());