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