1 /*
2  * Copyright (C) 2010 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.preference;
18 
19 import android.annotation.StringRes;
20 import android.content.Context;
21 import android.content.res.TypedArray;
22 import android.util.AttributeSet;
23 import android.view.View;
24 import android.widget.Checkable;
25 import android.widget.CompoundButton;
26 import android.widget.Switch;
27 
28 /**
29  * A {@link Preference} that provides a two-state toggleable option.
30  * <p>
31  * This preference will store a boolean into the SharedPreferences.
32  *
33  * @attr ref android.R.styleable#SwitchPreference_summaryOff
34  * @attr ref android.R.styleable#SwitchPreference_summaryOn
35  * @attr ref android.R.styleable#SwitchPreference_switchTextOff
36  * @attr ref android.R.styleable#SwitchPreference_switchTextOn
37  * @attr ref android.R.styleable#SwitchPreference_disableDependentsState
38  */
39 public class SwitchPreference extends TwoStatePreference {
40     private final Listener mListener = new Listener();
41 
42     // Switch text for on and off states
43     private CharSequence mSwitchOn;
44     private CharSequence mSwitchOff;
45 
46     private class Listener implements CompoundButton.OnCheckedChangeListener {
47         @Override
onCheckedChanged(CompoundButton buttonView, boolean isChecked)48         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
49             if (!callChangeListener(isChecked)) {
50                 // Listener didn't like it, change it back.
51                 // CompoundButton will make sure we don't recurse.
52                 buttonView.setChecked(!isChecked);
53                 return;
54             }
55 
56             SwitchPreference.this.setChecked(isChecked);
57         }
58     }
59 
60     /**
61      * Construct a new SwitchPreference with the given style options.
62      *
63      * @param context The Context that will style this preference
64      * @param attrs Style attributes that differ from the default
65      * @param defStyleAttr An attribute in the current theme that contains a
66      *        reference to a style resource that supplies default values for
67      *        the view. Can be 0 to not look for defaults.
68      * @param defStyleRes A resource identifier of a style resource that
69      *        supplies default values for the view, used only if
70      *        defStyleAttr is 0 or can not be found in the theme. Can be 0
71      *        to not look for defaults.
72      */
SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)73     public SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
74         super(context, attrs, defStyleAttr, defStyleRes);
75 
76         TypedArray a = context.obtainStyledAttributes(attrs,
77                 com.android.internal.R.styleable.SwitchPreference, defStyleAttr, defStyleRes);
78         setSummaryOn(a.getString(com.android.internal.R.styleable.SwitchPreference_summaryOn));
79         setSummaryOff(a.getString(com.android.internal.R.styleable.SwitchPreference_summaryOff));
80         setSwitchTextOn(a.getString(
81                 com.android.internal.R.styleable.SwitchPreference_switchTextOn));
82         setSwitchTextOff(a.getString(
83                 com.android.internal.R.styleable.SwitchPreference_switchTextOff));
84         setDisableDependentsState(a.getBoolean(
85                 com.android.internal.R.styleable.SwitchPreference_disableDependentsState, false));
86         a.recycle();
87     }
88 
89     /**
90      * Construct a new SwitchPreference with the given style options.
91      *
92      * @param context The Context that will style this preference
93      * @param attrs Style attributes that differ from the default
94      * @param defStyleAttr An attribute in the current theme that contains a
95      *        reference to a style resource that supplies default values for
96      *        the view. Can be 0 to not look for defaults.
97      */
SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr)98     public SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
99         this(context, attrs, defStyleAttr, 0);
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      */
SwitchPreference(Context context, AttributeSet attrs)108     public SwitchPreference(Context context, AttributeSet attrs) {
109         this(context, attrs, com.android.internal.R.attr.switchPreferenceStyle);
110     }
111 
112     /**
113      * Construct a new SwitchPreference with default style options.
114      *
115      * @param context The Context that will style this preference
116      */
SwitchPreference(Context context)117     public SwitchPreference(Context context) {
118         this(context, null);
119     }
120 
121     @Override
onBindView(View view)122     protected void onBindView(View view) {
123         super.onBindView(view);
124 
125         View checkableView = view.findViewById(com.android.internal.R.id.switch_widget);
126         if (checkableView != null && checkableView instanceof Checkable) {
127             if (checkableView instanceof Switch) {
128                 final Switch switchView = (Switch) checkableView;
129                 switchView.setOnCheckedChangeListener(null);
130             }
131 
132             ((Checkable) checkableView).setChecked(mChecked);
133 
134             if (checkableView instanceof Switch) {
135                 final Switch switchView = (Switch) checkableView;
136                 switchView.setTextOn(mSwitchOn);
137                 switchView.setTextOff(mSwitchOff);
138                 switchView.setOnCheckedChangeListener(mListener);
139             }
140         }
141 
142         syncSummaryView(view);
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(@tringRes int resId)173     public void setSwitchTextOn(@StringRes 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(@tringRes int resId)183     public void setSwitchTextOff(@StringRes 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