• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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 com.android.settings.widget;
18 
19 import android.content.Context;
20 import android.content.res.TypedArray;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.util.AttributeSet;
24 import android.util.TypedValue;
25 import android.view.LayoutInflater;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.widget.CompoundButton;
29 import android.widget.LinearLayout;
30 
31 import android.widget.Switch;
32 import android.widget.TextView;
33 import com.android.settings.R;
34 
35 import java.util.ArrayList;
36 
37 public class SwitchBar extends LinearLayout implements CompoundButton.OnCheckedChangeListener,
38         View.OnClickListener {
39 
40     public static interface OnSwitchChangeListener {
41         /**
42          * Called when the checked state of the Switch has changed.
43          *
44          * @param switchView The Switch view whose state has changed.
45          * @param isChecked  The new checked state of switchView.
46          */
onSwitchChanged(Switch switchView, boolean isChecked)47         void onSwitchChanged(Switch switchView, boolean isChecked);
48     }
49 
50     private ToggleSwitch mSwitch;
51     private TextView mTextView;
52 
53     private ArrayList<OnSwitchChangeListener> mSwitchChangeListeners =
54             new ArrayList<OnSwitchChangeListener>();
55 
56     private static int[] MARGIN_ATTRIBUTES = {
57             R.attr.switchBarMarginStart, R.attr.switchBarMarginEnd};
58 
SwitchBar(Context context)59     public SwitchBar(Context context) {
60         this(context, null);
61     }
62 
SwitchBar(Context context, AttributeSet attrs)63     public SwitchBar(Context context, AttributeSet attrs) {
64         this(context, attrs, 0);
65     }
66 
SwitchBar(Context context, AttributeSet attrs, int defStyleAttr)67     public SwitchBar(Context context, AttributeSet attrs, int defStyleAttr) {
68         this(context, attrs, defStyleAttr, 0);
69     }
70 
SwitchBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)71     public SwitchBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
72         super(context, attrs, defStyleAttr, defStyleRes);
73 
74         LayoutInflater.from(context).inflate(R.layout.switch_bar, this);
75 
76         final TypedArray a = context.obtainStyledAttributes(attrs, MARGIN_ATTRIBUTES);
77         int switchBarMarginStart = (int) a.getDimension(0, 0);
78         int switchBarMarginEnd = (int) a.getDimension(1, 0);
79         a.recycle();
80 
81         mTextView = (TextView) findViewById(R.id.switch_text);
82         mTextView.setText(R.string.switch_off_text);
83         ViewGroup.MarginLayoutParams lp = (MarginLayoutParams) mTextView.getLayoutParams();
84         lp.setMarginStart(switchBarMarginStart);
85 
86         mSwitch = (ToggleSwitch) findViewById(R.id.switch_widget);
87         // Prevent onSaveInstanceState() to be called as we are managing the state of the Switch
88         // on our own
89         mSwitch.setSaveEnabled(false);
90         lp = (MarginLayoutParams) mSwitch.getLayoutParams();
91         lp.setMarginEnd(switchBarMarginEnd);
92 
93         addOnSwitchChangeListener(new OnSwitchChangeListener() {
94             @Override
95             public void onSwitchChanged(Switch switchView, boolean isChecked) {
96                 setTextViewLabel(isChecked);
97             }
98         });
99 
100         setOnClickListener(this);
101 
102         // Default is hide
103         setVisibility(View.GONE);
104     }
105 
setTextViewLabel(boolean isChecked)106     public void setTextViewLabel(boolean isChecked) {
107         mTextView.setText(isChecked ? R.string.switch_on_text : R.string.switch_off_text);
108     }
109 
setChecked(boolean checked)110     public void setChecked(boolean checked) {
111         setTextViewLabel(checked);
112         mSwitch.setChecked(checked);
113     }
114 
setCheckedInternal(boolean checked)115     public void setCheckedInternal(boolean checked) {
116         setTextViewLabel(checked);
117         mSwitch.setCheckedInternal(checked);
118     }
119 
isChecked()120     public boolean isChecked() {
121         return mSwitch.isChecked();
122     }
123 
setEnabled(boolean enabled)124     public void setEnabled(boolean enabled) {
125         super.setEnabled(enabled);
126         mTextView.setEnabled(enabled);
127         mSwitch.setEnabled(enabled);
128     }
129 
getSwitch()130     public final ToggleSwitch getSwitch() {
131         return mSwitch;
132     }
133 
show()134     public void show() {
135         if (!isShowing()) {
136             setVisibility(View.VISIBLE);
137             mSwitch.setOnCheckedChangeListener(this);
138         }
139     }
140 
hide()141     public void hide() {
142         if (isShowing()) {
143             setVisibility(View.GONE);
144             mSwitch.setOnCheckedChangeListener(null);
145         }
146     }
147 
isShowing()148     public boolean isShowing() {
149         return (getVisibility() == View.VISIBLE);
150     }
151 
152     @Override
onClick(View v)153     public void onClick(View v) {
154         final boolean isChecked = !mSwitch.isChecked();
155         setChecked(isChecked);
156     }
157 
propagateChecked(boolean isChecked)158     public void propagateChecked(boolean isChecked) {
159         final int count = mSwitchChangeListeners.size();
160         for (int n = 0; n < count; n++) {
161             mSwitchChangeListeners.get(n).onSwitchChanged(mSwitch, isChecked);
162         }
163     }
164 
165     @Override
onCheckedChanged(CompoundButton buttonView, boolean isChecked)166     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
167         propagateChecked(isChecked);
168     }
169 
addOnSwitchChangeListener(OnSwitchChangeListener listener)170     public void addOnSwitchChangeListener(OnSwitchChangeListener listener) {
171         if (mSwitchChangeListeners.contains(listener)) {
172             throw new IllegalStateException("Cannot add twice the same OnSwitchChangeListener");
173         }
174         mSwitchChangeListeners.add(listener);
175     }
176 
removeOnSwitchChangeListener(OnSwitchChangeListener listener)177     public void removeOnSwitchChangeListener(OnSwitchChangeListener listener) {
178         if (!mSwitchChangeListeners.contains(listener)) {
179             throw new IllegalStateException("Cannot remove OnSwitchChangeListener");
180         }
181         mSwitchChangeListeners.remove(listener);
182     }
183 
184     static class SavedState extends BaseSavedState {
185         boolean checked;
186         boolean visible;
187 
SavedState(Parcelable superState)188         SavedState(Parcelable superState) {
189             super(superState);
190         }
191 
192         /**
193          * Constructor called from {@link #CREATOR}
194          */
SavedState(Parcel in)195         private SavedState(Parcel in) {
196             super(in);
197             checked = (Boolean)in.readValue(null);
198             visible = (Boolean)in.readValue(null);
199         }
200 
201         @Override
writeToParcel(Parcel out, int flags)202         public void writeToParcel(Parcel out, int flags) {
203             super.writeToParcel(out, flags);
204             out.writeValue(checked);
205             out.writeValue(visible);
206         }
207 
208         @Override
toString()209         public String toString() {
210             return "SwitchBar.SavedState{"
211                     + Integer.toHexString(System.identityHashCode(this))
212                     + " checked=" + checked
213                     + " visible=" + visible + "}";
214         }
215 
216         public static final Parcelable.Creator<SavedState> CREATOR
217                 = new Parcelable.Creator<SavedState>() {
218             public SavedState createFromParcel(Parcel in) {
219                 return new SavedState(in);
220             }
221 
222             public SavedState[] newArray(int size) {
223                 return new SavedState[size];
224             }
225         };
226     }
227 
228     @Override
onSaveInstanceState()229     public Parcelable onSaveInstanceState() {
230         Parcelable superState = super.onSaveInstanceState();
231 
232         SavedState ss = new SavedState(superState);
233         ss.checked = mSwitch.isChecked();
234         ss.visible = isShowing();
235         return ss;
236     }
237 
238     @Override
onRestoreInstanceState(Parcelable state)239     public void onRestoreInstanceState(Parcelable state) {
240         SavedState ss = (SavedState) state;
241 
242         super.onRestoreInstanceState(ss.getSuperState());
243 
244         mSwitch.setCheckedInternal(ss.checked);
245         setTextViewLabel(ss.checked);
246         setVisibility(ss.visible ? View.VISIBLE : View.GONE);
247         mSwitch.setOnCheckedChangeListener(ss.visible ? this : null);
248 
249         requestLayout();
250     }
251 }
252