Loading res/layout/accessibility_shortcut_secondary_action.xmldeleted 100644 → 0 +0 −100 Original line number Diff line number Diff line <?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> src/com/android/settings/accessibility/ShortcutPreference.java +31 −24 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 -> { Loading @@ -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) -> { Loading @@ -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(); } }); } /** Loading tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java +32 −20 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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) { Loading @@ -61,47 +63,57 @@ 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 setCheckedTrue_getToggleIsTrue() { mShortcutPreference.setChecked(true); public void clickPreference_settingsClicked() { mShortcutPreference.onBindViewHolder(mViewHolder); mShortcutPreference.setOnClickCallback(mListener); assertThat(mShortcutPreference.isChecked()).isEqualTo(true); mShortcutPreference.performClick(); assertThat(mResult).isEqualTo(SETTINGS_CLICKED); } @Test public void performClickOnPreference_settingsClicked() { mShortcutPreference.onBindViewHolder(mPreferenceViewHolder); mShortcutPreference.setOnClickCallback(mListener); mShortcutPreference.performClick(); public void setCheckedTrue_getToggleIsTrue() { mShortcutPreference.setChecked(true); assertThat(mResult).isEqualTo(SETTINGS_CLICKED); assertThat(mShortcutPreference.isChecked()).isEqualTo(true); } } Loading
res/layout/accessibility_shortcut_secondary_action.xmldeleted 100644 → 0 +0 −100 Original line number Diff line number Diff line <?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>
src/com/android/settings/accessibility/ShortcutPreference.java +31 −24 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 -> { Loading @@ -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) -> { Loading @@ -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(); } }); } /** Loading
tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java +32 −20 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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) { Loading @@ -61,47 +63,57 @@ 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 setCheckedTrue_getToggleIsTrue() { mShortcutPreference.setChecked(true); public void clickPreference_settingsClicked() { mShortcutPreference.onBindViewHolder(mViewHolder); mShortcutPreference.setOnClickCallback(mListener); assertThat(mShortcutPreference.isChecked()).isEqualTo(true); mShortcutPreference.performClick(); assertThat(mResult).isEqualTo(SETTINGS_CLICKED); } @Test public void performClickOnPreference_settingsClicked() { mShortcutPreference.onBindViewHolder(mPreferenceViewHolder); mShortcutPreference.setOnClickCallback(mListener); mShortcutPreference.performClick(); public void setCheckedTrue_getToggleIsTrue() { mShortcutPreference.setChecked(true); assertThat(mResult).isEqualTo(SETTINGS_CLICKED); assertThat(mShortcutPreference.isChecked()).isEqualTo(true); } }