Update ShortcutPreference with expressive design

To make hearing devices screen meets the expressive design, the shortcut
preference need to be updated.

Flag: EXEMPT flag by System prop
Bug: 349675952
Test: atest ShortcutPreferenceTest
Test: manually check the UI, screenshots attached on bug
Change-Id: I04a86c0592c5aa0e096b827a9ee65b12cf13ecf5
This commit is contained in:
Angela Wang
2024-12-26 08:37:13 +00:00
parent 242b3b8abd
commit 0af1dbae4e
3 changed files with 64 additions and 145 deletions

View File

@@ -1,100 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2019 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:minHeight="?android:attr/listPreferredItemHeightSmall"
android:gravity="center_vertical"
android:clipToPadding="false">
<LinearLayout
android:id="@+id/main_frame"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:layout_weight="1"
android:gravity="start|center_vertical">
<FrameLayout
android:id="@+id/icon_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="56dp"
android:paddingEnd="12dp"
android:paddingTop="16dp"
android:paddingBottom="4dp">
<ImageView
android:id="@android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp">
<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:hyphenationFrequency="normalFast"
android:lineBreakWordStyle="phrase"
android:ellipsize="marquee" />
<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:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary"
android:hyphenationFrequency="normalFast"
android:lineBreakWordStyle="phrase"
android:maxLines="10" />
</RelativeLayout>
</LinearLayout>
<View
android:id="@+id/divider"
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:background="?android:attr/listDivider" />
<!-- 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="end|center_vertical"
android:paddingHorizontal="?android:attr/listPreferredItemPaddingEnd"
android:minWidth="58dp"
android:orientation="vertical" />
</LinearLayout>

View File

@@ -18,22 +18,23 @@ package com.android.settings.accessibility;
import android.content.Context;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
import com.android.settingslib.widget.SettingsThemeHelper;
import com.android.settingslib.widget.TwoTargetPreference;
/**
* Preference that can enable accessibility shortcut and let users choose which shortcut type they
* prefer to use.
*/
public class ShortcutPreference extends Preference {
public class ShortcutPreference extends TwoTargetPreference {
/**
* Interface definition for a callback to be invoked when the toggle or settings has been
@@ -61,8 +62,6 @@ public class ShortcutPreference extends Preference {
ShortcutPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.accessibility_shortcut_secondary_action);
setWidgetLayoutResource(androidx.preference.R.layout.preference_widget_switch_compat);
setIconSpaceReserved(false);
// Treat onSettingsClicked as this preference's click.
setOnPreferenceClickListener(preference -> {
@@ -71,25 +70,30 @@ public class ShortcutPreference extends Preference {
});
}
@Override
protected int getSecondTargetResId() {
return SettingsThemeHelper.isExpressiveTheme(getContext())
? com.android.settingslib.widget.theme.R.layout
.settingslib_expressive_preference_switch
: androidx.preference.R.layout.preference_widget_switch_compat;
}
int getSwitchResId() {
return SettingsThemeHelper.isExpressiveTheme(getContext())
? com.android.settingslib.widget.theme.R.id.switchWidget
: androidx.preference.R.id.switchWidget;
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
final TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
outValue, true);
final LinearLayout mainFrame = holder.itemView.findViewById(R.id.main_frame);
if (mainFrame != null) {
mainFrame.setOnClickListener(view -> callOnSettingsClicked());
mainFrame.setClickable(mSettingsEditable);
mainFrame.setFocusable(mSettingsEditable);
mainFrame.setBackgroundResource(
mSettingsEditable ? outValue.resourceId : /* Remove background */ 0);
final View widgetFrame = holder.findViewById(android.R.id.widget_frame);
if (widgetFrame instanceof LinearLayout linearLayout) {
linearLayout.setGravity(Gravity.END | Gravity.CENTER_VERTICAL);
}
CompoundButton switchWidget =
holder.itemView.findViewById(androidx.preference.R.id.switchWidget);
CompoundButton switchWidget = holder.itemView.findViewById(getSwitchResId());
if (switchWidget != null) {
// Consumes move events to ignore drag actions.
switchWidget.setOnTouchListener((v, event) -> {
@@ -101,18 +105,21 @@ public class ShortcutPreference extends Preference {
switchWidget.setOnClickListener(view -> callOnToggleClicked());
switchWidget.setClickable(mSettingsEditable);
switchWidget.setFocusable(mSettingsEditable);
switchWidget.setBackgroundResource(
mSettingsEditable ? outValue.resourceId : /* Remove background */ 0);
}
final View divider = holder.itemView.findViewById(R.id.divider);
final View divider = holder.itemView.findViewById(
com.android.settingslib.widget.preference.twotarget.R.id.two_target_divider);
if (divider != null) {
divider.setVisibility(mSettingsEditable ? View.VISIBLE : View.GONE);
}
holder.itemView.setOnClickListener(view -> callOnToggleClicked());
holder.itemView.setClickable(!mSettingsEditable);
holder.itemView.setFocusable(!mSettingsEditable);
holder.itemView.setOnClickListener(view -> {
if (mSettingsEditable) {
callOnSettingsClicked();
} else {
callOnToggleClicked();
}
});
}
/**

View File

@@ -21,11 +21,13 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import androidx.preference.PreferenceViewHolder;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settingslib.widget.SettingsThemeHelper;
import org.junit.Before;
import org.junit.Test;
@@ -40,10 +42,10 @@ public class ShortcutPreferenceTest {
private static final String SETTINGS_CLICKED = "settings_clicked";
private ShortcutPreference mShortcutPreference;
private PreferenceViewHolder mPreferenceViewHolder;
private PreferenceViewHolder mViewHolder;
private String mResult;
private ShortcutPreference.OnClickCallback mListener =
private final ShortcutPreference.OnClickCallback mListener =
new ShortcutPreference.OnClickCallback() {
@Override
public void onToggleClicked(ShortcutPreference preference) {
@@ -61,30 +63,49 @@ public class ShortcutPreferenceTest {
final Context context = ApplicationProvider.getApplicationContext();
mShortcutPreference = new ShortcutPreference(context, null);
int resID = SettingsThemeHelper.isExpressiveTheme(context)
? com.android.settingslib.widget.preference.twotarget.R.layout
.settingslib_expressive_preference_two_target
: com.android.settingslib.widget.preference.twotarget.R.layout
.preference_two_target;
final LayoutInflater inflater = LayoutInflater.from(context);
final View view =
inflater.inflate(R.layout.accessibility_shortcut_secondary_action, null);
mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(view);
final View view = inflater.inflate(resID, null);
mViewHolder = PreferenceViewHolder.createInstanceForTests(view);
final LinearLayout widget = mViewHolder.itemView.findViewById(android.R.id.widget_frame);
inflater.inflate(mShortcutPreference.getSecondTargetResId(), widget, true);
}
@Test
public void clickToggle_toggleClicked() {
mShortcutPreference.onBindViewHolder(mPreferenceViewHolder);
mShortcutPreference.onBindViewHolder(mViewHolder);
mShortcutPreference.setOnClickCallback(mListener);
mPreferenceViewHolder.itemView.performClick();
CompoundButton switchWidget = mViewHolder.itemView.findViewById(
mShortcutPreference.getSwitchResId());
assert switchWidget != null;
switchWidget.performClick();
assertThat(mResult).isEqualTo(TOGGLE_CLICKED);
assertThat(mShortcutPreference.isChecked()).isTrue();
}
@Test
public void clickSettings_settingsClicked() {
mShortcutPreference.onBindViewHolder(mPreferenceViewHolder);
public void clickItem_settingsClicked() {
mShortcutPreference.onBindViewHolder(mViewHolder);
mShortcutPreference.setOnClickCallback(mListener);
final View settings = mPreferenceViewHolder.itemView.findViewById(R.id.main_frame);
settings.performClick();
mViewHolder.itemView.performClick();
assertThat(mResult).isEqualTo(SETTINGS_CLICKED);
}
@Test
public void clickPreference_settingsClicked() {
mShortcutPreference.onBindViewHolder(mViewHolder);
mShortcutPreference.setOnClickCallback(mListener);
mShortcutPreference.performClick();
assertThat(mResult).isEqualTo(SETTINGS_CLICKED);
}
@@ -95,13 +116,4 @@ public class ShortcutPreferenceTest {
assertThat(mShortcutPreference.isChecked()).isEqualTo(true);
}
@Test
public void performClickOnPreference_settingsClicked() {
mShortcutPreference.onBindViewHolder(mPreferenceViewHolder);
mShortcutPreference.setOnClickCallback(mListener);
mShortcutPreference.performClick();
assertThat(mResult).isEqualTo(SETTINGS_CLICKED);
}
}