1 /*
2  * Copyright (C) 2007 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.widget;
18 
19 import android.content.Context;
20 import android.content.res.TypedArray;
21 import android.graphics.drawable.Drawable;
22 import android.graphics.drawable.LayerDrawable;
23 import android.util.AttributeSet;
24 
25 /**
26  * Displays checked/unchecked states as a button
27  * with a "light" indicator and by default accompanied with the text "ON" or "OFF".
28  *
29  * <p>See the <a href="{@docRoot}guide/topics/ui/controls/togglebutton.html">Toggle Buttons</a>
30  * guide.</p>
31  *
32  * @attr ref android.R.styleable#ToggleButton_textOn
33  * @attr ref android.R.styleable#ToggleButton_textOff
34  * @attr ref android.R.styleable#ToggleButton_disabledAlpha
35  */
36 public class ToggleButton extends CompoundButton {
37     private CharSequence mTextOn;
38     private CharSequence mTextOff;
39 
40     private Drawable mIndicatorDrawable;
41 
42     private static final int NO_ALPHA = 0xFF;
43     private float mDisabledAlpha;
44 
ToggleButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)45     public ToggleButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
46         super(context, attrs, defStyleAttr, defStyleRes);
47 
48         final TypedArray a = context.obtainStyledAttributes(
49                 attrs, com.android.internal.R.styleable.ToggleButton, defStyleAttr, defStyleRes);
50         mTextOn = a.getText(com.android.internal.R.styleable.ToggleButton_textOn);
51         mTextOff = a.getText(com.android.internal.R.styleable.ToggleButton_textOff);
52         mDisabledAlpha = a.getFloat(com.android.internal.R.styleable.ToggleButton_disabledAlpha, 0.5f);
53         syncTextState();
54         a.recycle();
55     }
56 
ToggleButton(Context context, AttributeSet attrs, int defStyleAttr)57     public ToggleButton(Context context, AttributeSet attrs, int defStyleAttr) {
58         this(context, attrs, defStyleAttr, 0);
59     }
60 
ToggleButton(Context context, AttributeSet attrs)61     public ToggleButton(Context context, AttributeSet attrs) {
62         this(context, attrs, com.android.internal.R.attr.buttonStyleToggle);
63     }
64 
ToggleButton(Context context)65     public ToggleButton(Context context) {
66         this(context, null);
67     }
68 
69     @Override
setChecked(boolean checked)70     public void setChecked(boolean checked) {
71         super.setChecked(checked);
72 
73         syncTextState();
74     }
75 
syncTextState()76     private void syncTextState() {
77         boolean checked = isChecked();
78         if (checked && mTextOn != null) {
79             setText(mTextOn);
80         } else if (!checked && mTextOff != null) {
81             setText(mTextOff);
82         }
83     }
84 
85     /**
86      * Returns the text for when the button is in the checked state.
87      *
88      * @return The text.
89      */
getTextOn()90     public CharSequence getTextOn() {
91         return mTextOn;
92     }
93 
94     /**
95      * Sets the text for when the button is in the checked state.
96      *
97      * @param textOn The text.
98      */
setTextOn(CharSequence textOn)99     public void setTextOn(CharSequence textOn) {
100         mTextOn = textOn;
101     }
102 
103     /**
104      * Returns the text for when the button is not in the checked state.
105      *
106      * @return The text.
107      */
getTextOff()108     public CharSequence getTextOff() {
109         return mTextOff;
110     }
111 
112     /**
113      * Sets the text for when the button is not in the checked state.
114      *
115      * @param textOff The text.
116      */
setTextOff(CharSequence textOff)117     public void setTextOff(CharSequence textOff) {
118         mTextOff = textOff;
119     }
120 
121     @Override
onFinishInflate()122     protected void onFinishInflate() {
123         super.onFinishInflate();
124 
125         updateReferenceToIndicatorDrawable(getBackground());
126     }
127 
128     @Override
setBackgroundDrawable(Drawable d)129     public void setBackgroundDrawable(Drawable d) {
130         super.setBackgroundDrawable(d);
131 
132         updateReferenceToIndicatorDrawable(d);
133     }
134 
updateReferenceToIndicatorDrawable(Drawable backgroundDrawable)135     private void updateReferenceToIndicatorDrawable(Drawable backgroundDrawable) {
136         if (backgroundDrawable instanceof LayerDrawable) {
137             LayerDrawable layerDrawable = (LayerDrawable) backgroundDrawable;
138             mIndicatorDrawable =
139                     layerDrawable.findDrawableByLayerId(com.android.internal.R.id.toggle);
140         } else {
141             mIndicatorDrawable = null;
142         }
143     }
144 
145     @Override
drawableStateChanged()146     protected void drawableStateChanged() {
147         super.drawableStateChanged();
148 
149         if (mIndicatorDrawable != null) {
150             mIndicatorDrawable.setAlpha(isEnabled() ? NO_ALPHA : (int) (NO_ALPHA * mDisabledAlpha));
151         }
152     }
153 
154     @Override
getAccessibilityClassName()155     public CharSequence getAccessibilityClassName() {
156         return ToggleButton.class.getName();
157     }
158 }
159