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