• 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 android.content.Context;
20 import android.content.res.TypedArray;
21 import android.support.v4.content.res.TypedArrayUtils;
22 import android.support.v7.widget.SwitchCompat;
23 import android.util.AttributeSet;
24 import android.view.View;
25 import android.view.accessibility.AccessibilityManager;
26 import android.widget.Checkable;
27 import 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 */
40 public 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
onCheckedChanged(CompoundButton buttonView, boolean isChecked)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      */
SwitchPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)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      */
SwitchPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr)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      */
SwitchPreferenceCompat(Context context, AttributeSet attrs)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      */
SwitchPreferenceCompat(Context context)130     public SwitchPreferenceCompat(Context context) {
131         this(context, null);
132     }
133 
134     @Override
onBindViewHolder(PreferenceViewHolder holder)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      */
setSwitchTextOn(CharSequence onText)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      */
setSwitchTextOff(CharSequence offText)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      */
setSwitchTextOn(int resId)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      */
setSwitchTextOff(int resId)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      */
getSwitchTextOn()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      */
getSwitchTextOff()194     public CharSequence getSwitchTextOff() {
195         return mSwitchOff;
196     }
197 
198     /**
199      * @hide
200      */
201     @Override
performClick(View view)202     protected void performClick(View view) {
203         super.performClick(view);
204         syncViewIfAccessibilityEnabled(view);
205     }
206 
syncViewIfAccessibilityEnabled(View view)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 
syncSwitchView(View view)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