diff options
| author | 2021-05-12 20:25:55 +0800 | |
|---|---|---|
| committer | 2021-05-14 17:55:34 +0800 | |
| commit | e49dc874d36e57647980a3083d110bb3856a1989 (patch) | |
| tree | fdb87ec94d7909a616b07eed0ed625e9d45f673c | |
| parent | 90cff49c35f5978a2766af17d908b31fec34a734 (diff) | |
Update ActionButtonsPreference style
- Add rounded background
- Add divider between buttons
Screenshots:
https://screenshot.googleplex.com/5b3fanqgpbpufyD.png
https://screenshot.googleplex.com/5jG85UeVk64pAMg.png
Bug: 187923403
Test: atest ActionButtonsPreferenceTest
Change-Id: I04bebbfc676c5c5d019a4dce1b8e31bfc69360d7
| -rw-r--r-- | packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml | 11 | ||||
| -rw-r--r-- | packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml | 25 | ||||
| -rw-r--r-- | packages/SettingsLib/ActionButtonsPreference/res/layout-v31/settingslib_action_buttons.xml | 78 | ||||
| -rw-r--r-- | packages/SettingsLib/ActionButtonsPreference/res/layout/settingslib_action_buttons.xml (renamed from packages/SettingsLib/ActionButtonsPreference/res/layout/settings_action_buttons.xml) | 10 | ||||
| -rw-r--r-- | packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml | 5 | ||||
| -rw-r--r-- | packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java | 72 | ||||
| -rw-r--r-- | packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java | 110 |
7 files changed, 296 insertions, 15 deletions
diff --git a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml index a19f7afbb5f8..22b25a31ae07 100644 --- a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml +++ b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml @@ -23,4 +23,15 @@ column="15"/> </issue> + <issue + id="NewApi" + message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 21)" + errorLine1=" android:radius="?android:attr/dialogCornerRadius"" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml" + line="23" + column="9"/> + </issue> + </issues> diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml new file mode 100644 index 000000000000..ae3834dc0d9d --- /dev/null +++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. + --> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:shape="rectangle"> + <solid android:color="?androidprv:attr/colorSurface" /> + <corners + android:radius="?android:attr/dialogCornerRadius" + /> +</shape>
\ No newline at end of file diff --git a/packages/SettingsLib/ActionButtonsPreference/res/layout-v31/settingslib_action_buttons.xml b/packages/SettingsLib/ActionButtonsPreference/res/layout-v31/settingslib_action_buttons.xml new file mode 100644 index 000000000000..ba612d76fa57 --- /dev/null +++ b/packages/SettingsLib/ActionButtonsPreference/res/layout-v31/settingslib_action_buttons.xml @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. + --> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="8dp" + android:paddingHorizontal="8dp" + android:orientation="horizontal" + android:background="@drawable/settingslib_rounded_background"> + + <Button + android:id="@+id/button1" + style="@style/SettingsLibActionButton" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1"/> + + <View + android:id="@+id/divider1" + android:layout_width="1dp" + android:layout_height="match_parent" + android:paddingHorizontal="4dp" + android:visibility="gone" + android:background="?android:colorBackground" /> + + <Button + android:id="@+id/button2" + style="@style/SettingsLibActionButton" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1"/> + + <View + android:id="@+id/divider2" + android:layout_width="1dp" + android:layout_height="match_parent" + android:paddingHorizontal="4dp" + android:visibility="gone" + android:background="?android:colorBackground" /> + + <Button + android:id="@+id/button3" + style="@style/SettingsLibActionButton" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1"/> + + <View + android:id="@+id/divider3" + android:layout_width="1dp" + android:layout_height="match_parent" + android:paddingHorizontal="4dp" + android:visibility="gone" + android:background="?android:colorBackground" /> + + <Button + android:id="@+id/button4" + style="@style/SettingsLibActionButton" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1"/> +</LinearLayout> diff --git a/packages/SettingsLib/ActionButtonsPreference/res/layout/settings_action_buttons.xml b/packages/SettingsLib/ActionButtonsPreference/res/layout/settingslib_action_buttons.xml index 4f47113bbafa..55df34ff0d44 100644 --- a/packages/SettingsLib/ActionButtonsPreference/res/layout/settings_action_buttons.xml +++ b/packages/SettingsLib/ActionButtonsPreference/res/layout/settingslib_action_buttons.xml @@ -24,29 +24,29 @@ <Button android:id="@+id/button1" - style="@style/SettingsActionButton" + style="@style/SettingsLibActionButton" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1"/> <Button android:id="@+id/button2" - style="@style/SettingsActionButton" + style="@style/SettingsLibActionButton" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1"/> <Button android:id="@+id/button3" - style="@style/SettingsActionButton" + style="@style/SettingsLibActionButton" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1"/> <Button android:id="@+id/button4" - style="@style/SettingsActionButton" + style="@style/SettingsLibActionButton" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1"/> -</LinearLayout>
\ No newline at end of file +</LinearLayout> diff --git a/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml b/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml index efa508dcde62..42c7d76a80e9 100644 --- a/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml +++ b/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml @@ -16,11 +16,10 @@ --> <resources> - <style name="SettingsActionButton" parent="android:Widget.DeviceDefault.Button.Borderless.Colored"> + <style name="SettingsLibActionButton" parent="android:Widget.DeviceDefault.Button.Borderless.Colored"> <item name="android:drawablePadding">4dp</item> <item name="android:drawableTint">@*android:color/btn_colored_borderless_text_material</item> - <item name="android:layout_marginEnd">8dp</item> <item name="android:paddingTop">20dp</item> <item name="android:paddingBottom">20dp</item> </style> -</resources>
\ No newline at end of file +</resources> diff --git a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java index 8b46cc608fd1..aeda7ac5d086 100644 --- a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java +++ b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java @@ -27,16 +27,20 @@ import android.widget.Button; import androidx.annotation.DrawableRes; import androidx.annotation.StringRes; +import androidx.core.os.BuildCompat; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; +import java.util.ArrayList; +import java.util.List; + /** * This preference provides a four buttons layout with Settings style. * It looks like below * - * -------------------------------------------------- - * button1 | button2 | button3 | button4 | - * -------------------------------------------------- + * --------------------------------------- + * - button1 | button2 | button3 | button4 - + * --------------------------------------- * * User can set title / icon / click listener for each button. * @@ -49,10 +53,16 @@ import androidx.preference.PreferenceViewHolder; public class ActionButtonsPreference extends Preference { private static final String TAG = "ActionButtonPreference"; + private final ButtonInfo mButton1Info = new ButtonInfo(); private final ButtonInfo mButton2Info = new ButtonInfo(); private final ButtonInfo mButton3Info = new ButtonInfo(); private final ButtonInfo mButton4Info = new ButtonInfo(); + private final List<ButtonInfo> mVisibleButtonInfos = new ArrayList<>(4); + + private View mDivider1; + private View mDivider2; + private View mDivider3; public ActionButtonsPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { @@ -76,25 +86,49 @@ public class ActionButtonsPreference extends Preference { } private void init() { - setLayoutResource(R.layout.settings_action_buttons); + setLayoutResource(R.layout.settingslib_action_buttons); setSelectable(false); } @Override public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); - holder.setDividerAllowedAbove(true); - holder.setDividerAllowedBelow(true); + if (!BuildCompat.isAtLeastS()) { + holder.setDividerAllowedAbove(true); + holder.setDividerAllowedBelow(true); + } mButton1Info.mButton = (Button) holder.findViewById(R.id.button1); mButton2Info.mButton = (Button) holder.findViewById(R.id.button2); mButton3Info.mButton = (Button) holder.findViewById(R.id.button3); mButton4Info.mButton = (Button) holder.findViewById(R.id.button4); + mDivider1 = holder.findViewById(R.id.divider1); + mDivider2 = holder.findViewById(R.id.divider2); + mDivider3 = holder.findViewById(R.id.divider3); + mButton1Info.setUpButton(); mButton2Info.setUpButton(); mButton3Info.setUpButton(); mButton4Info.setUpButton(); + + // Add visible button into list only + if (mButton1Info.isVisible()) { + mVisibleButtonInfos.add(mButton1Info); + } + if (mButton2Info.isVisible()) { + mVisibleButtonInfos.add(mButton2Info); + } + if (mButton3Info.isVisible()) { + mVisibleButtonInfos.add(mButton3Info); + } + if (mButton4Info.isVisible()) { + mVisibleButtonInfos.add(mButton4Info); + } + + setupDivider1(); + setupDivider2(); + setupDivider3(); } /** @@ -357,6 +391,28 @@ public class ActionButtonsPreference extends Preference { return this; } + private void setupDivider1() { + // Display divider1 only if button1 and button2 is visible + if (mDivider1 != null && mButton1Info.isVisible() && mButton2Info.isVisible()) { + mDivider1.setVisibility(View.VISIBLE); + } + } + + private void setupDivider2() { + // Display divider2 only if button3 is visible and button2 or button3 is visible + if (mDivider2 != null && mButton3Info.isVisible() + && (mButton1Info.isVisible() || mButton2Info.isVisible())) { + mDivider2.setVisibility(View.VISIBLE); + } + } + + private void setupDivider3() { + // Display divider3 only if button4 is visible and 2 visible buttons at least + if (mDivider3 != null && mVisibleButtonInfos.size() > 1 && mButton4Info.isVisible()) { + mDivider3.setVisibility(View.VISIBLE); + } + } + static class ButtonInfo { private Button mButton; private CharSequence mText; @@ -379,6 +435,10 @@ public class ActionButtonsPreference extends Preference { } } + boolean isVisible() { + return mButton.getVisibility() == View.VISIBLE; + } + /** * By default, four buttons are visible. * However, there are two cases which button should be invisible. diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java index e24b52594ba6..9f31ceff7230 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java @@ -48,7 +48,7 @@ public class ActionButtonsPreferenceTest { @Before public void setUp() { mContext = RuntimeEnvironment.application; - mRootView = View.inflate(mContext, R.layout.settings_action_buttons, null /* parent */); + mRootView = View.inflate(mContext, R.layout.settingslib_action_buttons, null /* parent */); mHolder = PreferenceViewHolder.createInstanceForTests(mRootView); mPref = new ActionButtonsPreference(mContext); } @@ -251,6 +251,114 @@ public class ActionButtonsPreferenceTest { assertThat(drawablesAroundText[1 /* top */]).isNull(); } + @Test + public void onBindViewHolder_setAllButton_shouldShowAllDivider() { + mPref.setButton1Text(R.string.install_other_apps); + mPref.setButton2Text(R.string.install_other_apps); + mPref.setButton3Text(R.string.install_other_apps); + mPref.setButton4Text(R.string.install_other_apps); + + mPref.onBindViewHolder(mHolder); + + assertThat(mRootView.findViewById(R.id.divider1).getVisibility()) + .isEqualTo(View.VISIBLE); + assertThat(mRootView.findViewById(R.id.divider2).getVisibility()) + .isEqualTo(View.VISIBLE); + assertThat(mRootView.findViewById(R.id.divider3).getVisibility()) + .isEqualTo(View.VISIBLE); + } + + @Test + public void onBindViewHolder_setAllButtonWithoutButton2_shouldHideDivider1() { + mPref.setButton1Text(R.string.install_other_apps); + mPref.setButton3Text(R.string.install_other_apps); + mPref.setButton4Text(R.string.install_other_apps); + + mPref.onBindViewHolder(mHolder); + + assertThat(mRootView.findViewById(R.id.divider1).getVisibility()) + .isEqualTo(View.GONE); + assertThat(mRootView.findViewById(R.id.divider2).getVisibility()) + .isEqualTo(View.VISIBLE); + assertThat(mRootView.findViewById(R.id.divider3).getVisibility()) + .isEqualTo(View.VISIBLE); + } + + @Test + public void onBindViewHolder_setAllButtonWithoutButton3_shouldHideDivider2() { + mPref.setButton1Text(R.string.install_other_apps); + mPref.setButton2Text(R.string.install_other_apps); + mPref.setButton4Text(R.string.install_other_apps); + + mPref.onBindViewHolder(mHolder); + + assertThat(mRootView.findViewById(R.id.divider1).getVisibility()) + .isEqualTo(View.VISIBLE); + assertThat(mRootView.findViewById(R.id.divider2).getVisibility()) + .isEqualTo(View.GONE); + assertThat(mRootView.findViewById(R.id.divider3).getVisibility()) + .isEqualTo(View.VISIBLE); + } + + @Test + public void onBindViewHolder_setButton1And4_shouldShowDivider3Only() { + mPref.setButton1Text(R.string.install_other_apps); + mPref.setButton4Text(R.string.install_other_apps); + + mPref.onBindViewHolder(mHolder); + + assertThat(mRootView.findViewById(R.id.divider1).getVisibility()) + .isEqualTo(View.GONE); + assertThat(mRootView.findViewById(R.id.divider2).getVisibility()) + .isEqualTo(View.GONE); + assertThat(mRootView.findViewById(R.id.divider3).getVisibility()) + .isEqualTo(View.VISIBLE); + } + + @Test + public void onBindViewHolder_setOneButtonOnly_noDivider() { + mPref.setButton4Text(R.string.install_other_apps); + + mPref.onBindViewHolder(mHolder); + + assertThat(mRootView.findViewById(R.id.divider1).getVisibility()) + .isEqualTo(View.GONE); + assertThat(mRootView.findViewById(R.id.divider2).getVisibility()) + .isEqualTo(View.GONE); + assertThat(mRootView.findViewById(R.id.divider3).getVisibility()) + .isEqualTo(View.GONE); + } + + @Test + public void onBindViewHolder_setButton1And2_shouldShowDivider1Only() { + mPref.setButton1Text(R.string.install_other_apps); + mPref.setButton2Text(R.string.install_other_apps); + + mPref.onBindViewHolder(mHolder); + + assertThat(mRootView.findViewById(R.id.divider1).getVisibility()) + .isEqualTo(View.VISIBLE); + assertThat(mRootView.findViewById(R.id.divider2).getVisibility()) + .isEqualTo(View.GONE); + assertThat(mRootView.findViewById(R.id.divider3).getVisibility()) + .isEqualTo(View.GONE); + } + + @Test + public void onBindViewHolder_setButton1And3_shouldShowDivider2Only() { + mPref.setButton1Text(R.string.install_other_apps); + mPref.setButton3Text(R.string.install_other_apps); + + mPref.onBindViewHolder(mHolder); + + assertThat(mRootView.findViewById(R.id.divider1).getVisibility()) + .isEqualTo(View.GONE); + assertThat(mRootView.findViewById(R.id.divider2).getVisibility()) + .isEqualTo(View.VISIBLE); + assertThat(mRootView.findViewById(R.id.divider3).getVisibility()) + .isEqualTo(View.GONE); + } + public static ActionButtonsPreference createMock() { final ActionButtonsPreference pref = mock(ActionButtonsPreference.class); when(pref.setButton1Text(anyInt())).thenReturn(pref); |