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

Commit b5ec99bf authored by Angela Wang's avatar Angela Wang Committed by Android (Google) Code Review
Browse files

Merge "Update ShortcutPreference with expressive design" into main

parents 7c861dc6 0af1dbae
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);
    }
}