Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0af1dbae authored by Angela Wang's avatar Angela Wang
Browse files

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
parent 242b3b8a
Loading
Loading
Loading
Loading
+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>
+31 −24
Original line number Diff line number Diff line
@@ -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();
            }
        });
    }

    /**
+32 −20
Original line number Diff line number Diff line
@@ -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,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);
    }
}