SwitchPreferenceCompat.java revision c67647d83261aad33d42309c52aa75e05ea9daf7
1/* 2* Copyright (C) 2015 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 17package android.support.v7.preference; 18 19import android.content.Context; 20import android.content.res.TypedArray; 21import android.support.v4.content.res.TypedArrayUtils; 22import android.support.v7.widget.SwitchCompat; 23import android.util.AttributeSet; 24import android.view.View; 25import android.view.accessibility.AccessibilityManager; 26import android.widget.Checkable; 27import android.widget.CompoundButton; 28 29/** 30* A {@link Preference} that provides a two-state toggleable option. 31* <p> 32* This preference will store a boolean into the SharedPreferences. 33* 34* @attr ref android.R.styleable#SwitchPreference_summaryOff 35* @attr ref android.R.styleable#SwitchPreference_summaryOn 36* @attr ref android.R.styleable#SwitchPreference_switchTextOff 37* @attr ref android.R.styleable#SwitchPreference_switchTextOn 38* @attr ref android.R.styleable#SwitchPreference_disableDependentsState 39*/ 40public class SwitchPreferenceCompat extends TwoStatePreference { 41 private final Listener mListener = new Listener(); 42 43 // Switch text for on and off states 44 private CharSequence mSwitchOn; 45 private CharSequence mSwitchOff; 46 47 private class Listener implements CompoundButton.OnCheckedChangeListener { 48 @Override 49 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 50 if (!callChangeListener(isChecked)) { 51 // Listener didn't like it, change it back. 52 // CompoundButton will make sure we don't recurse. 53 buttonView.setChecked(!isChecked); 54 return; 55 } 56 57 SwitchPreferenceCompat.this.setChecked(isChecked); 58 } 59 } 60 61 /** 62 * Construct a new SwitchPreference with the given style options. 63 * 64 * @param context The Context that will style this preference 65 * @param attrs Style attributes that differ from the default 66 * @param defStyleAttr An attribute in the current theme that contains a 67 * reference to a style resource that supplies default values for 68 * the view. Can be 0 to not look for defaults. 69 * @param defStyleRes A resource identifier of a style resource that 70 * supplies default values for the view, used only if 71 * defStyleAttr is 0 or can not be found in the theme. Can be 0 72 * to not look for defaults. 73 */ 74 public SwitchPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr, 75 int defStyleRes) { 76 super(context, attrs, defStyleAttr, defStyleRes); 77 78 TypedArray a = context.obtainStyledAttributes(attrs, 79 R.styleable.SwitchPreferenceCompat, defStyleAttr, defStyleRes); 80 81 setSummaryOn(TypedArrayUtils.getString(a, R.styleable.SwitchPreferenceCompat_summaryOn, 82 R.styleable.SwitchPreferenceCompat_android_summaryOn)); 83 84 setSummaryOff(TypedArrayUtils.getString(a, R.styleable.SwitchPreferenceCompat_summaryOff, 85 R.styleable.SwitchPreferenceCompat_android_summaryOff)); 86 87 setSwitchTextOn(TypedArrayUtils.getString(a, 88 R.styleable.SwitchPreferenceCompat_switchTextOn, 89 R.styleable.SwitchPreferenceCompat_android_switchTextOn)); 90 91 setSwitchTextOff(TypedArrayUtils.getString(a, 92 R.styleable.SwitchPreferenceCompat_switchTextOff, 93 R.styleable.SwitchPreferenceCompat_android_switchTextOff)); 94 95 setDisableDependentsState(TypedArrayUtils.getBoolean(a, 96 R.styleable.SwitchPreferenceCompat_disableDependentsState, 97 R.styleable.SwitchPreferenceCompat_android_disableDependentsState, false)); 98 99 a.recycle(); 100 } 101 102 /** 103 * Construct a new SwitchPreference with the given style options. 104 * 105 * @param context The Context that will style this preference 106 * @param attrs Style attributes that differ from the default 107 * @param defStyleAttr An attribute in the current theme that contains a 108 * reference to a style resource that supplies default values for 109 * the view. Can be 0 to not look for defaults. 110 */ 111 public SwitchPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr) { 112 this(context, attrs, defStyleAttr, 0); 113 } 114 115 /** 116 * Construct a new SwitchPreference with the given style options. 117 * 118 * @param context The Context that will style this preference 119 * @param attrs Style attributes that differ from the default 120 */ 121 public SwitchPreferenceCompat(Context context, AttributeSet attrs) { 122 this(context, attrs, R.attr.switchPreferenceCompatStyle); 123 } 124 125 /** 126 * Construct a new SwitchPreference with default style options. 127 * 128 * @param context The Context that will style this preference 129 */ 130 public SwitchPreferenceCompat(Context context) { 131 this(context, null); 132 } 133 134 @Override 135 public void onBindViewHolder(PreferenceViewHolder holder) { 136 super.onBindViewHolder(holder); 137 View switchView = holder.findViewById(R.id.switchWidget); 138 syncSwitchView(switchView); 139 syncSummaryView(holder); 140 } 141 142 /** 143 * Set the text displayed on the switch widget in the on state. 144 * This should be a very short string; one word if possible. 145 * 146 * @param onText Text to display in the on state 147 */ 148 public void setSwitchTextOn(CharSequence onText) { 149 mSwitchOn = onText; 150 notifyChanged(); 151 } 152 153 /** 154 * Set the text displayed on the switch widget in the off state. 155 * This should be a very short string; one word if possible. 156 * 157 * @param offText Text to display in the off state 158 */ 159 public void setSwitchTextOff(CharSequence offText) { 160 mSwitchOff = offText; 161 notifyChanged(); 162 } 163 164 /** 165 * Set the text displayed on the switch widget in the on state. 166 * This should be a very short string; one word if possible. 167 * 168 * @param resId The text as a string resource ID 169 */ 170 public void setSwitchTextOn(int resId) { 171 setSwitchTextOn(getContext().getString(resId)); 172 } 173 174 /** 175 * Set the text displayed on the switch widget in the off state. 176 * This should be a very short string; one word if possible. 177 * 178 * @param resId The text as a string resource ID 179 */ 180 public void setSwitchTextOff(int resId) { 181 setSwitchTextOff(getContext().getString(resId)); 182 } 183 184 /** 185 * @return The text that will be displayed on the switch widget in the on state 186 */ 187 public CharSequence getSwitchTextOn() { 188 return mSwitchOn; 189 } 190 191 /** 192 * @return The text that will be displayed on the switch widget in the off state 193 */ 194 public CharSequence getSwitchTextOff() { 195 return mSwitchOff; 196 } 197 198 /** 199 * @hide 200 */ 201 @Override 202 protected void performClick(View view) { 203 super.performClick(view); 204 syncViewIfAccessibilityEnabled(view); 205 } 206 207 private void syncViewIfAccessibilityEnabled(View view) { 208 AccessibilityManager accessibilityManager = (AccessibilityManager) 209 getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); 210 if (!accessibilityManager.isEnabled()) { 211 return; 212 } 213 214 View switchView = view.findViewById(R.id.switchWidget); 215 syncSwitchView(switchView); 216 217 View summaryView = view.findViewById(android.R.id.summary); 218 syncSummaryView(summaryView); 219 } 220 221 private void syncSwitchView(View view) { 222 if (view instanceof SwitchCompat) { 223 final SwitchCompat switchView = (SwitchCompat) view; 224 switchView.setOnCheckedChangeListener(null); 225 } 226 if (view instanceof Checkable) { 227 ((Checkable) view).setChecked(mChecked); 228 } 229 if (view instanceof SwitchCompat) { 230 final SwitchCompat switchView = (SwitchCompat) view; 231 switchView.setTextOn(mSwitchOn); 232 switchView.setTextOff(mSwitchOff); 233 switchView.setOnCheckedChangeListener(mListener); 234 } 235 } 236} 237