1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.accessibility; 18 19 import android.content.Context; 20 import android.util.AttributeSet; 21 import android.view.Gravity; 22 import android.view.MotionEvent; 23 import android.view.View; 24 import android.widget.CompoundButton; 25 import android.widget.LinearLayout; 26 27 import androidx.annotation.NonNull; 28 import androidx.annotation.Nullable; 29 import androidx.preference.PreferenceViewHolder; 30 31 import com.android.settings.R; 32 import com.android.settingslib.widget.SettingsThemeHelper; 33 import com.android.settingslib.widget.TwoTargetPreference; 34 35 /** 36 * Preference that can enable accessibility shortcut and let users choose which shortcut type they 37 * prefer to use. 38 */ 39 public class ShortcutPreference extends TwoTargetPreference { 40 41 /** 42 * Interface definition for a callback to be invoked when the toggle or settings has been 43 * clicked. 44 */ 45 public interface OnClickCallback { 46 /** 47 * Called when the settings view has been clicked. 48 * 49 * @param preference The clicked preference 50 */ onSettingsClicked(ShortcutPreference preference)51 void onSettingsClicked(ShortcutPreference preference); 52 53 /** 54 * Called when the toggle in ShortcutPreference has been clicked. 55 * 56 * @param preference The clicked preference 57 */ onToggleClicked(ShortcutPreference preference)58 void onToggleClicked(ShortcutPreference preference); 59 } 60 61 private OnClickCallback mClickCallback = null; 62 private boolean mChecked = false; 63 private boolean mSettingsEditable = true; 64 ShortcutPreference(@onNull Context context, @Nullable AttributeSet attrs)65 public ShortcutPreference(@NonNull Context context, @Nullable AttributeSet attrs) { 66 super(context, attrs); 67 setIconSpaceReserved(false); 68 // Treat onSettingsClicked as this preference's click. 69 setOnPreferenceClickListener(preference -> { 70 callOnSettingsClicked(); 71 return true; 72 }); 73 } 74 75 @Override getSecondTargetResId()76 protected int getSecondTargetResId() { 77 return SettingsThemeHelper.isExpressiveTheme(getContext()) 78 ? com.android.settingslib.widget.theme.R.layout 79 .settingslib_expressive_preference_switch 80 : androidx.preference.R.layout.preference_widget_switch_compat; 81 } 82 getSwitchResId()83 int getSwitchResId() { 84 return SettingsThemeHelper.isExpressiveTheme(getContext()) 85 ? com.android.settingslib.widget.theme.R.id.switchWidget 86 : androidx.preference.R.id.switchWidget; 87 } 88 89 @Override onBindViewHolder(PreferenceViewHolder holder)90 public void onBindViewHolder(PreferenceViewHolder holder) { 91 super.onBindViewHolder(holder); 92 93 final View widgetFrame = holder.findViewById(android.R.id.widget_frame); 94 if (widgetFrame instanceof LinearLayout linearLayout) { 95 linearLayout.setGravity(Gravity.END | Gravity.CENTER_VERTICAL); 96 } 97 98 CompoundButton switchWidget = holder.itemView.findViewById(getSwitchResId()); 99 if (switchWidget != null) { 100 // Consumes move events to ignore drag actions. 101 switchWidget.setOnTouchListener((v, event) -> { 102 return event.getActionMasked() == MotionEvent.ACTION_MOVE; 103 }); 104 switchWidget.setContentDescription( 105 getContext().getText(R.string.accessibility_shortcut_settings)); 106 switchWidget.setChecked(mChecked); 107 switchWidget.setOnClickListener(view -> callOnToggleClicked()); 108 switchWidget.setClickable(mSettingsEditable); 109 switchWidget.setFocusable(mSettingsEditable); 110 } 111 112 final View divider = holder.itemView.findViewById( 113 com.android.settingslib.widget.preference.twotarget.R.id.two_target_divider); 114 if (divider != null) { 115 divider.setVisibility(mSettingsEditable ? View.VISIBLE : View.GONE); 116 } 117 118 holder.itemView.setOnClickListener(view -> { 119 if (mSettingsEditable) { 120 callOnSettingsClicked(); 121 } else { 122 callOnToggleClicked(); 123 } 124 }); 125 } 126 127 /** 128 * Sets the shortcut toggle according to checked value. 129 * 130 * @param checked the state value of shortcut toggle 131 */ setChecked(boolean checked)132 public void setChecked(boolean checked) { 133 if (mChecked != checked) { 134 mChecked = checked; 135 notifyChanged(); 136 } 137 } 138 139 /** 140 * Gets the checked value of shortcut toggle. 141 * 142 * @return the checked value of shortcut toggle 143 */ isChecked()144 public boolean isChecked() { 145 return mChecked; 146 } 147 148 /** 149 * Sets the editable state of Settings view. If the view cannot edited, it makes the settings 150 * and toggle be not touchable. The main ui handles touch event directly by {@link #onClick}. 151 */ setSettingsEditable(boolean enabled)152 public void setSettingsEditable(boolean enabled) { 153 if (mSettingsEditable != enabled) { 154 mSettingsEditable = enabled; 155 notifyChanged(); 156 } 157 } 158 isSettingsEditable()159 public boolean isSettingsEditable() { 160 return mSettingsEditable; 161 } 162 163 /** 164 * Sets the callback to be invoked when this preference is clicked by the user. 165 * 166 * @param callback the callback to be invoked 167 */ setOnClickCallback(OnClickCallback callback)168 public void setOnClickCallback(OnClickCallback callback) { 169 mClickCallback = callback; 170 } 171 callOnSettingsClicked()172 private void callOnSettingsClicked() { 173 if (mClickCallback != null) { 174 mClickCallback.onSettingsClicked(this); 175 } 176 } 177 callOnToggleClicked()178 private void callOnToggleClicked() { 179 setChecked(!mChecked); 180 if (mClickCallback != null) { 181 mClickCallback.onToggleClicked(this); 182 } 183 } 184 } 185