From 2ad0e3dcd845a86f0d2dfaf61018d011fbe1efc9 Mon Sep 17 00:00:00 2001 From: Mill Chen Date: Sat, 6 Feb 2021 01:03:43 +0800 Subject: [PATCH] Create a collapsing toolbar based activity On Android S, each of subsetting pages will have a collapsing toolbar to enlarge its title. However, there are many different pages from differennt apps. So we extracted a base activity with collapsing toolbar layout so it is easier to enbale a collapsing toolbar in their own pages. Bug: 179380824 Test: visual verified Change-Id: Ic505d65320081589d1e1b5eb4bd2af7a06e60d39 --- packages/SettingsLib/Android.bp | 1 + .../CollapsingToolbarBaseActivity/Android.bp | 14 +++ .../AndroidManifest.xml | 23 +++++ .../layout/collapsing_toolbar_base_layout.xml | 60 +++++++++++ .../res/values-night/themes.xml | 23 +++++ .../res/values/styles.xml | 30 ++++++ .../res/values/themes.xml | 23 +++++ .../AdjustableToolbarLayout.java | 92 +++++++++++++++++ .../CollapsingToolbarBaseActivity.java | 99 +++++++++++++++++++ 9 files changed, 365 insertions(+) create mode 100644 packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp create mode 100644 packages/SettingsLib/CollapsingToolbarBaseActivity/AndroidManifest.xml create mode 100644 packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout/collapsing_toolbar_base_layout.xml create mode 100644 packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night/themes.xml create mode 100644 packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml create mode 100644 packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/themes.xml create mode 100644 packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java create mode 100644 packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp index e8ad16bba417c..f2a0e1cb83bd8 100644 --- a/packages/SettingsLib/Android.bp +++ b/packages/SettingsLib/Android.bp @@ -66,6 +66,7 @@ java_defaults { "SettingsLibBannerMessagePreference", "SettingsLibFooterPreference", "SettingsLibUsageProgressBarPreference", + "SettingsLibCollapsingToolbarBaseActivity", ], } diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp new file mode 100644 index 0000000000000..c23ff05f34ab6 --- /dev/null +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp @@ -0,0 +1,14 @@ +android_library { + name: "SettingsLibCollapsingToolbarBaseActivity", + + srcs: ["src/**/*.java"], + resource_dirs: ["res"], + + static_libs: [ + "androidx.annotation_annotation", + "androidx.core_core", + "com.google.android.material_material", + ], + sdk_version: "system_current", + min_sdk_version: "21", +} diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/AndroidManifest.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/AndroidManifest.xml new file mode 100644 index 0000000000000..dabba68321340 --- /dev/null +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/AndroidManifest.xml @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout/collapsing_toolbar_base_layout.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout/collapsing_toolbar_base_layout.xml new file mode 100644 index 0000000000000..e376930645cec --- /dev/null +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout/collapsing_toolbar_base_layout.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night/themes.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night/themes.xml new file mode 100644 index 0000000000000..e20775ef45fd1 --- /dev/null +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night/themes.xml @@ -0,0 +1,23 @@ + + + + + \ No newline at end of file diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml new file mode 100644 index 0000000000000..e1a64d446ea2d --- /dev/null +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml @@ -0,0 +1,30 @@ + + + + + + + + + \ No newline at end of file diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/themes.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/themes.xml new file mode 100644 index 0000000000000..de545b0711e38 --- /dev/null +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/themes.xml @@ -0,0 +1,23 @@ + + + + + \ No newline at end of file diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java new file mode 100644 index 0000000000000..e75a978574565 --- /dev/null +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2021 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.settingslib.collapsingtoolbar; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.google.android.material.appbar.CollapsingToolbarLayout; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * A customized version of CollapsingToolbarLayout that can apply different font size based on + * the line count of its title. + */ +public class AdjustableToolbarLayout extends CollapsingToolbarLayout { + + private static final int TOOLBAR_MAX_LINE_NUMBER = 2; + + public AdjustableToolbarLayout(@NonNull Context context) { + this(context, null); + + } + + public AdjustableToolbarLayout(@NonNull Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public AdjustableToolbarLayout(@NonNull Context context, @Nullable AttributeSet attrs, + int defStyleAttr) { + super(context, attrs, defStyleAttr); + initCollapsingToolbar(); + } + + private void initCollapsingToolbar() { + this.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) { + setExpandedTitleTextAppearance(R.style.CollapsingToolbarTitle_MoreThanTwoLines); + } else { + setExpandedTitleTextAppearance(R.style.CollapsingToolbarTitle); + } + } + }); + } + + /** + * Returns a number of title line count for CollapsingToolbarLayout so that facilitates the + * determination to apply what kind of font size. Since the title of CollapsingToolbarLayout is + * drawn in a canvas and the text process is wrapped in a CollapsingTextHelper, the way we used + * here is to get the line count from the CollapsingTextHelper via Java Reflection. + */ + private int getLineCount() { + try { + final Field textHelperField = this.getClass().getDeclaredField("collapsingTextHelper"); + textHelperField.setAccessible(true); + final Object textHelperObj = textHelperField.get(this); + + 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; + } + } +} diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java new file mode 100644 index 0000000000000..637805fc81c3a --- /dev/null +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2021 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.settingslib.collapsingtoolbar; + +import android.app.ActionBar; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toolbar; + +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; + +import com.google.android.material.appbar.CollapsingToolbarLayout; + +/** + * A base Activity that has a collapsing toolbar layout is used for the activities intending to + * enable the collapsing toolbar function. + */ +public class CollapsingToolbarBaseActivity extends FragmentActivity { + + private CollapsingToolbarLayout mCollapsingToolbarLayout; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + super.setContentView(R.layout.collapsing_toolbar_base_layout); + mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar); + + final Toolbar toolbar = findViewById(R.id.action_bar); + setActionBar(toolbar); + + // Enable title and home button by default + final ActionBar actionBar = getActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + actionBar.setHomeButtonEnabled(true); + actionBar.setDisplayShowTitleEnabled(true); + } + } + + @Override + public void setContentView(int layoutResID) { + final ViewGroup parent = findViewById(R.id.content_frame); + if (parent != null) { + parent.removeAllViews(); + } + LayoutInflater.from(this).inflate(layoutResID, parent); + } + + @Override + public void setContentView(View view) { + ((ViewGroup) findViewById(R.id.content_frame)).addView(view); + } + + @Override + public void setContentView(View view, ViewGroup.LayoutParams params) { + ((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); + } + + /** + * Returns an instance of collapsing toolbar. + */ + public CollapsingToolbarLayout getCollapsingToolbarLayout() { + return mCollapsingToolbarLayout; + } +}