Merge changes Id1ed4455,I73e62733 into main
* changes:
Make Preferences more visible with colored rounded rectangle background and an arrow icon
Provides BackgroundPreference that can set background statically or dynamically
diff --git a/res/layout/preference_background.xml b/res/layout/preference_background.xml
new file mode 100644
index 0000000..129076a
--- /dev/null
+++ b/res/layout/preference_background.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright (C) 2024 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.
+ -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingVertical="@dimen/settingslib_switchbar_margin"
+ android:background="@android:color/transparent">
+
+ <LinearLayout
+ android:id="@+id/background"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingStart="@dimen/settingslib_switchbar_padding_left"
+ android:paddingEnd="@dimen/settingslib_switchbar_padding_right"
+ android:orientation="horizontal"
+ android:gravity="start|center_vertical"
+ android:baselineAligned="false">
+
+ <FrameLayout
+ android:id="@+id/icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="15dip"
+ android:layout_marginRight="15dip">
+ <androidx.preference.internal.PreferenceImageView
+ android:id="@android:id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:maxWidth="48dp"
+ app:maxHeight="48dp" />
+ </FrameLayout>
+
+ <RelativeLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="6dip"
+ android:layout_marginRight="6dip"
+ android:layout_marginTop="@dimen/settingslib_switch_title_margin"
+ android:layout_marginBottom="@dimen/settingslib_switch_title_margin"
+ android:layout_weight="1">
+
+ <TextView android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:textColor="?android:attr/textColorPrimary"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:hyphenationFrequency="normalFast"
+ android:lineBreakWordStyle="phrase" />
+
+ <TextView android:id="@android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:layout_alignLeft="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary"
+ android:hyphenationFrequency="normalFast"
+ android:lineBreakWordStyle="phrase"
+ android:maxLines="4"
+ android:scrollbars="none"/>
+ </RelativeLayout>
+
+ <!-- Preference should place its actual preference widget here. -->
+ <LinearLayout android:id="@android:id/widget_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:orientation="vertical" />
+ </LinearLayout>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/preference_widget_arrow.xml b/res/layout/preference_widget_arrow.xml
new file mode 100644
index 0000000..ddeb669
--- /dev/null
+++ b/res/layout/preference_widget_arrow.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2024 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.
+-->
+
+<ImageView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical"
+ android:contentDescription="@null"
+ android:scaleType="center"
+ android:src="@drawable/ic_arrow_forward" />
\ No newline at end of file
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 40a7c58..200253a 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -198,4 +198,9 @@
<attr name="notification_importance_button_background_color_selected" format="color" />
<attr name="notification_importance_button_border_color_selected" format="color" />
<attr name="notification_importance_button_foreground_color_selected" format="color" />
+
+ <!-- For BackgroundPreference -->
+ <declare-styleable name="BackgroundPreference">
+ <attr name="background" format="reference" />
+ </declare-styleable>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 46c8f8c..c5d0017 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -152,10 +152,10 @@
<string name="bluetooth_pair_other_ear_dialog_left_ear_positive_button">Pair left ear</string>
<!-- Title for all hearing devices related controls section. [CHAR LIMIT=60] -->
<string name="bluetooth_device_controls_general">For all available hearing devices</string>
- <!-- Connected devices settings. Title of the preference to show the entrance of the hearing device controls related page. [CHAR LIMIT=65] -->
- <string name="bluetooth_device_controls_title">Hearing device settings</string>
- <!-- Connected devices settings. Title of the preference to show the entrance of the hearing device controls related page. [CHAR LIMIT=65] -->
- <string name="bluetooth_device_controls_summary">Shortcut, hearing aid compatibility</string>
+ <!-- Connected devices settings. Title of the preference to show the entrance of the hearing device settings related page. [CHAR LIMIT=65] -->
+ <string name="bluetooth_device_controls_title">More hearing device settings</string>
+ <!-- Connected devices settings. Summary of the preference to show the item in the hearing device settings related page. [CHAR LIMIT=120] -->
+ <string name="bluetooth_device_controls_summary">Change cross-device settings like shortcut, and telecoil controls</string>
<!-- Title for this device specific controls section. [CHAR LIMIT=30] -->
<string name="bluetooth_device_controls_specific">For this device</string>
<!-- Connected devices settings. Title of the preference to show the entrance of the audio output page. It can change different types of audio are played on phone or other bluetooth devices. [CHAR LIMIT=35] -->
diff --git a/src/com/android/settings/accessibility/ArrowPreference.java b/src/com/android/settings/accessibility/ArrowPreference.java
index 32e2bcb..ccee50d 100644
--- a/src/com/android/settings/accessibility/ArrowPreference.java
+++ b/src/com/android/settings/accessibility/ArrowPreference.java
@@ -22,17 +22,25 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.res.TypedArrayUtils;
-import androidx.preference.Preference;
import com.android.settings.R;
/**
- * A settings preference with colored rounded rectangle background and an arrow icon on the right
+ * A settings preference with colored rounded rectangle background and an arrow icon on the right.
*/
-public class ArrowPreference extends Preference {
+public class ArrowPreference extends BackgroundPreference {
- public ArrowPreference(@NonNull Context context) {
- this(context, null);
+ public ArrowPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ setBackground(
+ com.android.settingslib.widget.mainswitch.R.drawable.settingslib_switch_bar_bg_on);
+ setWidgetLayoutResource(R.layout.preference_widget_arrow);
+ }
+
+ public ArrowPreference(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
}
public ArrowPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
@@ -41,18 +49,7 @@
android.R.attr.preferenceStyle));
}
- public ArrowPreference(@NonNull Context context, @Nullable AttributeSet attrs,
- int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public ArrowPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- init();
- }
-
- private void init() {
- setLayoutResource(R.layout.arrow_preference);
+ public ArrowPreference(@NonNull Context context) {
+ this(context, null);
}
}
diff --git a/src/com/android/settings/accessibility/BackgroundPreference.java b/src/com/android/settings/accessibility/BackgroundPreference.java
new file mode 100644
index 0000000..ea56ac5
--- /dev/null
+++ b/src/com/android/settings/accessibility/BackgroundPreference.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2024 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.accessibility;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.LinearLayout;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.content.res.TypedArrayUtils;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settings.R;
+
+/**
+ * A preference with custom background.
+ */
+public class BackgroundPreference extends Preference {
+
+ private int mBackgroundId;
+
+ public BackgroundPreference(@NonNull Context context,
+ @Nullable AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ setLayoutResource(R.layout.preference_background);
+ setIconSpaceReserved(false);
+
+ final TypedArray styledAttrs = context.obtainStyledAttributes(attrs,
+ R.styleable.BackgroundPreference);
+ mBackgroundId = styledAttrs.getResourceId(R.styleable.BackgroundPreference_background, 0);
+ styledAttrs.recycle();
+ }
+
+ public BackgroundPreference(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public BackgroundPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
+ this(context, attrs, TypedArrayUtils.getAttr(context,
+ androidx.preference.R.attr.preferenceStyle,
+ com.android.internal.R.attr.preferenceStyle), 0);
+ }
+
+ public BackgroundPreference(@NonNull Context context) {
+ this(context, null, TypedArrayUtils.getAttr(context,
+ androidx.preference.R.attr.preferenceStyle,
+ com.android.internal.R.attr.preferenceStyle), 0);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ final LinearLayout layout = (LinearLayout) holder.findViewById(R.id.background);
+ if (mBackgroundId != 0) {
+ final Drawable backgroundDrawable = getContext().getDrawable(mBackgroundId);
+ layout.setBackground(backgroundDrawable);
+ }
+ }
+
+ /**
+ * Sets the background to a given resource. The resource should refer to a Drawable object.
+ *
+ * @param resId The identifier of the resource.
+ */
+ public void setBackground(@DrawableRes int resId) {
+ if (mBackgroundId != resId) {
+ mBackgroundId = resId;
+ notifyChanged();
+ }
+ }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsController.java b/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsController.java
index 3d85ca2..162abc7 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsHearingDeviceControlsController.java
@@ -26,6 +26,7 @@
import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityHearingAidsFragment;
+import com.android.settings.accessibility.ArrowPreference;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -83,7 +84,7 @@
}
private Preference createHearingDeviceControlsPreference(Context context) {
- final Preference preference = new Preference(context);
+ final ArrowPreference preference = new ArrowPreference(context);
preference.setKey(KEY_HEARING_DEVICE_CONTROLS);
preference.setTitle(context.getString(R.string.bluetooth_device_controls_title));
preference.setSummary(context.getString(R.string.bluetooth_device_controls_summary));
diff --git a/tests/robotests/src/com/android/settings/accessibility/ArrowPreferenceTest.java b/tests/robotests/src/com/android/settings/accessibility/ArrowPreferenceTest.java
new file mode 100644
index 0000000..ff4a748
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/ArrowPreferenceTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2024 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.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link ArrowPreference} */
+@RunWith(RobolectricTestRunner.class)
+public class ArrowPreferenceTest {
+
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ private ArrowPreference mPreference;
+
+ @Before
+ public void setUp() {
+ mPreference = new ArrowPreference(mContext);
+ }
+
+ @Test
+ public void construct_withArrow() {
+ assertThat(mPreference.getWidgetLayoutResource()).isEqualTo(
+ R.layout.preference_widget_arrow);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/BackgroundPreferenceTest.java b/tests/robotests/src/com/android/settings/accessibility/BackgroundPreferenceTest.java
new file mode 100644
index 0000000..007d664
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/BackgroundPreferenceTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2024 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.accessibility;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import androidx.preference.PreferenceViewHolder;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link BackgroundPreference} */
+@RunWith(RobolectricTestRunner.class)
+public class BackgroundPreferenceTest {
+
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+
+ private View mRootView = new View(mContext);
+ @Spy
+ private PreferenceViewHolder mViewHolder = PreferenceViewHolder.createInstanceForTests(
+ mRootView);
+ @Spy
+ private LinearLayout mLinearLayout = new LinearLayout(mContext);
+ private BackgroundPreference mPreference;
+
+ @Before
+ public void setUp() {
+ mPreference = new BackgroundPreference(mContext);
+ }
+
+ @Test
+ public void setBackground_success() {
+ doReturn(mLinearLayout).when(mViewHolder).findViewById(R.id.background);
+
+ mPreference.setBackground(android.R.drawable.screen_background_dark);
+ mPreference.onBindViewHolder(mViewHolder);
+
+ verify(mLinearLayout).setBackground(any());
+ }
+}