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
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
</LinearLayout>
|
||||
@@ -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>
|
||||
</resources>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user