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