19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viveretteimport android.annotation.Nullable; 20911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viveretteimport android.graphics.PorterDuff; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.R; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 24911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viveretteimport android.content.res.ColorStateList; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Gravity; 32d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viveretteimport android.view.SoundEffectConstants; 337a36788f4a69b3ddaf8fb8e250e1a13bee7238faSteve Zeiglerimport android.view.ViewDebug; 34cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queruimport android.view.accessibility.AccessibilityEvent; 3513774d2e38e73ef4d0f6d0db3501ba032fa6da5aSvetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A button with two states, checked and unchecked. When the button is pressed 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or clicked, the state changes automatically. 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p><strong>XML attributes</strong></p> 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.R.styleable#CompoundButton 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * CompoundButton Attributes}, {@link android.R.styleable#Button Button 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Attributes}, {@link android.R.styleable#TextView TextView Attributes}, {@link 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android.R.styleable#View View Attributes} 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class CompoundButton extends Button implements Checkable { 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mChecked; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mButtonResource; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mBroadcasting; 55911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mButtonDrawable; 57a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette private ColorStateList mButtonTintList = null; 58b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette private PorterDuff.Mode mButtonTintMode = null; 59911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette private boolean mHasButtonTint = false; 60b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette private boolean mHasButtonTintMode = false; 61911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnCheckedChangeListener mOnCheckedChangeListener; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnCheckedChangeListener mOnCheckedChangeWidgetListener; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int[] CHECKED_STATE_SET = { 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R.attr.state_checked 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public CompoundButton(Context context) { 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, null); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public CompoundButton(Context context, AttributeSet attrs) { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, attrs, 0); 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 77617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public CompoundButton(Context context, AttributeSet attrs, int defStyleAttr) { 78617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette this(context, attrs, defStyleAttr, 0); 79617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette } 80617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette 81617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public CompoundButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 82617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette super(context, attrs, defStyleAttr, defStyleRes); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 84617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette final TypedArray a = context.obtainStyledAttributes( 85617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette attrs, com.android.internal.R.styleable.CompoundButton, defStyleAttr, defStyleRes); 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 87911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette final Drawable d = a.getDrawable(com.android.internal.R.styleable.CompoundButton_button); 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (d != null) { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setButtonDrawable(d); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 92b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette if (a.hasValue(R.styleable.CompoundButton_buttonTintMode)) { 93b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette mButtonTintMode = Drawable.parseTintMode(a.getInt( 94b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette R.styleable.CompoundButton_buttonTintMode, -1), mButtonTintMode); 95b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette mHasButtonTintMode = true; 96b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette } 974f64c048505a432e549ccb756634ecebf28f9e80Alan Viverette 98911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette if (a.hasValue(R.styleable.CompoundButton_buttonTint)) { 99a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mButtonTintList = a.getColorStateList(R.styleable.CompoundButton_buttonTint); 100911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette mHasButtonTint = true; 101911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette } 102911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette 103911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette final boolean checked = a.getBoolean( 104911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette com.android.internal.R.styleable.CompoundButton_checked, false); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setChecked(checked); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 108b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette 109b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette applyButtonTint(); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void toggle() { 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setChecked(!mChecked); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performClick() { 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project toggle(); 119d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette 120d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette final boolean handled = super.performClick(); 121d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette if (!handled) { 122d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette // View only makes a sound effect if the onClickListener was 123d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette // called, so we'll need to make one here instead. 124d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette playSoundEffect(SoundEffectConstants.CLICK); 125d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette } 126d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette 127d4e7790fee10e21b41a1c387c2734722bda56a0bAlan Viverette return handled; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1307a36788f4a69b3ddaf8fb8e250e1a13bee7238faSteve Zeigler @ViewDebug.ExportedProperty 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isChecked() { 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mChecked; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Changes the checked state of this button.</p> 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param checked true to check the button, false to uncheck it 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setChecked(boolean checked) { 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mChecked != checked) { 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChecked = checked; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refreshDrawableState(); 14477e9a28e2faa36f127231b842476d47f9823a83aAlan Viverette notifyViewAccessibilityStateChangedIfNeeded( 14577e9a28e2faa36f127231b842476d47f9823a83aAlan Viverette AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Avoid infinite recursions if setChecked() is called from a listener 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBroadcasting) { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcasting = true; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnCheckedChangeListener != null) { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnCheckedChangeListener.onCheckedChanged(this, mChecked); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnCheckedChangeWidgetListener != null) { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 159cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcasting = false; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when the checked state of this button 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * changes. 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener the callback to call on checked state change 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnCheckedChangeListener(OnCheckedChangeListener listener) { 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnCheckedChangeListener = listener; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when the checked state of this button 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * changes. This callback is used for internal purpose only. 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener the callback to call on checked state change 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void setOnCheckedChangeWidgetListener(OnCheckedChangeListener listener) { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnCheckedChangeWidgetListener = listener; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition for a callback to be invoked when the checked state 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of a compound button changed. 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static interface OnCheckedChangeListener { 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when the checked state of a compound button has changed. 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param buttonView The compound button view whose state has changed. 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param isChecked The new checked state of buttonView. 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onCheckedChanged(CompoundButton buttonView, boolean isChecked); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 200911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * Set the button graphic to a given Drawable, identified by its resource 201911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * id. 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 203911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * @param resid the resource id of the drawable to use as the button 204911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * graphic 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setButtonDrawable(int resid) { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (resid != 0 && resid == mButtonResource) { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mButtonResource = resid; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Drawable d = null; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mButtonResource != 0) { 2158eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette d = getContext().getDrawable(mButtonResource); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setButtonDrawable(d); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 221911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * Set the button graphic to a given Drawable 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 223911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * @param d The Drawable to use as the button graphic 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setButtonDrawable(Drawable d) { 226911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette if (mButtonDrawable != d) { 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mButtonDrawable != null) { 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mButtonDrawable.setCallback(null); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unscheduleDrawable(mButtonDrawable); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 231911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mButtonDrawable = d; 233911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette 234911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette if (d != null) { 235911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette d.setCallback(this); 236911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette d.setLayoutDirection(getLayoutDirection()); 237911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette if (d.isStateful()) { 238911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette d.setState(getDrawableState()); 239911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette } 240911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette d.setVisible(getVisibility() == VISIBLE, false); 241911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette setMinHeight(d.getIntrinsicHeight()); 242911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette applyButtonTint(); 243911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette } 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 245911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 247911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette /** 2484f64c048505a432e549ccb756634ecebf28f9e80Alan Viverette * Applies a tint to the button drawable. Does not modify the current tint 249b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette * mode, which is {@link PorterDuff.Mode#SRC_IN} by default. 250911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * <p> 251911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * Subsequent calls to {@link #setButtonDrawable(Drawable)} will 252911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * automatically mutate the drawable and apply the specified tint and tint 253911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * mode using 254a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette * {@link Drawable#setTintList(ColorStateList)}. 255911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * 256911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * @param tint the tint to apply, may be {@code null} to clear tint 257911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * 258911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * @attr ref android.R.styleable#CompoundButton_buttonTint 259a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette * @see #setButtonTintList(ColorStateList) 260a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette * @see Drawable#setTintList(ColorStateList) 261911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette */ 262a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public void setButtonTintList(@Nullable ColorStateList tint) { 263a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mButtonTintList = tint; 264911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette mHasButtonTint = true; 265911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette 266911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette applyButtonTint(); 267911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette } 268911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette 269911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette /** 270911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * @return the tint applied to the button drawable 271911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * @attr ref android.R.styleable#CompoundButton_buttonTint 272a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette * @see #setButtonTintList(ColorStateList) 273911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette */ 274911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette @Nullable 275a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public ColorStateList getButtonTintList() { 276a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette return mButtonTintList; 277911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette } 278911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette 279911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette /** 280911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * Specifies the blending mode used to apply the tint specified by 281a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette * {@link #setButtonTintList(ColorStateList)}} to the button drawable. The 282b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette * default mode is {@link PorterDuff.Mode#SRC_IN}. 283911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * 284911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * @param tintMode the blending mode used to apply the tint, may be 285911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * {@code null} to clear tint 286911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * @attr ref android.R.styleable#CompoundButton_buttonTintMode 2874f64c048505a432e549ccb756634ecebf28f9e80Alan Viverette * @see #getButtonTintMode() 288a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette * @see Drawable#setTintMode(PorterDuff.Mode) 289911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette */ 290911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette public void setButtonTintMode(@Nullable PorterDuff.Mode tintMode) { 2914f64c048505a432e549ccb756634ecebf28f9e80Alan Viverette mButtonTintMode = tintMode; 292b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette mHasButtonTintMode = true; 2934f64c048505a432e549ccb756634ecebf28f9e80Alan Viverette 2944f64c048505a432e549ccb756634ecebf28f9e80Alan Viverette applyButtonTint(); 295911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette } 296911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette 297911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette /** 298911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * @return the blending mode used to apply the tint to the button drawable 299911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette * @attr ref android.R.styleable#CompoundButton_buttonTintMode 3004f64c048505a432e549ccb756634ecebf28f9e80Alan Viverette * @see #setButtonTintMode(PorterDuff.Mode) 301911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette */ 302911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette @Nullable 303911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette public PorterDuff.Mode getButtonTintMode() { 304911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette return mButtonTintMode; 305911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette } 306911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette 307911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette private void applyButtonTint() { 308b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette if (mButtonDrawable != null && (mHasButtonTint || mHasButtonTintMode)) { 309911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette mButtonDrawable = mButtonDrawable.mutate(); 310b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette 311b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette if (mHasButtonTint) { 312b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette mButtonDrawable.setTintList(mButtonTintList); 313b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette } 314b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette 315b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette if (mHasButtonTintMode) { 316b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette mButtonDrawable.setTintMode(mButtonTintMode); 317b56f5d2ab18f881eb075b698e9ce1b4a4a09ff64Alan Viverette } 318d5133792391443521dc15f7da7de5d280e6703ddAlan Viverette 319d5133792391443521dc15f7da7de5d280e6703ddAlan Viverette // The drawable (or one of its children) may not have been 320d5133792391443521dc15f7da7de5d280e6703ddAlan Viverette // stateful before applying the tint, so let's try again. 321d5133792391443521dc15f7da7de5d280e6703ddAlan Viverette if (mButtonDrawable.isStateful()) { 322d5133792391443521dc15f7da7de5d280e6703ddAlan Viverette mButtonDrawable.setState(getDrawableState()); 323d5133792391443521dc15f7da7de5d280e6703ddAlan Viverette } 324911743652b597057a1bd7ef8a921e9ff8dce0f4aAlan Viverette } 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 32830401328c1026389171d454c934c15875c3f7ff0Svetoslav Ganov public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 32930401328c1026389171d454c934c15875c3f7ff0Svetoslav Ganov super.onInitializeAccessibilityEvent(event); 3308a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov event.setClassName(CompoundButton.class.getName()); 331736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov event.setChecked(mChecked); 332cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru } 333cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru 334cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru @Override 33513774d2e38e73ef4d0f6d0db3501ba032fa6da5aSvetoslav Ganov public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 33613774d2e38e73ef4d0f6d0db3501ba032fa6da5aSvetoslav Ganov super.onInitializeAccessibilityNodeInfo(info); 3378a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov info.setClassName(CompoundButton.class.getName()); 3380f55cc33f658b2793a12d609a0989348077324a4Svetoslav Ganov info.setCheckable(true); 33913774d2e38e73ef4d0f6d0db3501ba032fa6da5aSvetoslav Ganov info.setChecked(mChecked); 34013774d2e38e73ef4d0f6d0db3501ba032fa6da5aSvetoslav Ganov } 34113774d2e38e73ef4d0f6d0db3501ba032fa6da5aSvetoslav Ganov 34213774d2e38e73ef4d0f6d0db3501ba032fa6da5aSvetoslav Ganov @Override 3432842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio public int getCompoundPaddingLeft() { 3442842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio int padding = super.getCompoundPaddingLeft(); 3452842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio if (!isLayoutRtl()) { 3462842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio final Drawable buttonDrawable = mButtonDrawable; 3472842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio if (buttonDrawable != null) { 3482842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio padding += buttonDrawable.getIntrinsicWidth(); 3492842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio } 3502842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio } 3512842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio return padding; 3522842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio } 3532842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio 3542842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio @Override 3552842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio public int getCompoundPaddingRight() { 3562842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio int padding = super.getCompoundPaddingRight(); 3572842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio if (isLayoutRtl()) { 3582842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio final Drawable buttonDrawable = mButtonDrawable; 3592842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio if (buttonDrawable != null) { 3602842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio padding += buttonDrawable.getIntrinsicWidth(); 3612842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio } 3622842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio } 3632842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio return padding; 3642842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio } 3652842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio 366b878ddb56ec4e755706890110d76735176ff2295Fabrice Di Meglio /** 367b878ddb56ec4e755706890110d76735176ff2295Fabrice Di Meglio * @hide 368b878ddb56ec4e755706890110d76735176ff2295Fabrice Di Meglio */ 369b878ddb56ec4e755706890110d76735176ff2295Fabrice Di Meglio @Override 370b878ddb56ec4e755706890110d76735176ff2295Fabrice Di Meglio public int getHorizontalOffsetForDrawables() { 371b878ddb56ec4e755706890110d76735176ff2295Fabrice Di Meglio final Drawable buttonDrawable = mButtonDrawable; 372b878ddb56ec4e755706890110d76735176ff2295Fabrice Di Meglio return (buttonDrawable != null) ? buttonDrawable.getIntrinsicWidth() : 0; 373b878ddb56ec4e755706890110d76735176ff2295Fabrice Di Meglio } 374b878ddb56ec4e755706890110d76735176ff2295Fabrice Di Meglio 3752842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio @Override 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onDraw(Canvas canvas) { 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Drawable buttonDrawable = mButtonDrawable; 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (buttonDrawable != null) { 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK; 3802842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio final int drawableHeight = buttonDrawable.getIntrinsicHeight(); 3812842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio final int drawableWidth = buttonDrawable.getIntrinsicWidth(); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38361956606818918194a38e045a8e35e7108480e5eAlan Viverette final int top; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (verticalGravity) { 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Gravity.BOTTOM: 3862842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio top = getHeight() - drawableHeight; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Gravity.CENTER_VERTICAL: 3892842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio top = (getHeight() - drawableHeight) / 2; 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 39161956606818918194a38e045a8e35e7108480e5eAlan Viverette default: 39261956606818918194a38e045a8e35e7108480e5eAlan Viverette top = 0; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39461956606818918194a38e045a8e35e7108480e5eAlan Viverette final int bottom = top + drawableHeight; 39561956606818918194a38e045a8e35e7108480e5eAlan Viverette final int left = isLayoutRtl() ? getWidth() - drawableWidth : 0; 39661956606818918194a38e045a8e35e7108480e5eAlan Viverette final int right = isLayoutRtl() ? getWidth() : drawableWidth; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3982842679d3426295b6674dfcfb8591fad79de6cb2Fabrice Di Meglio buttonDrawable.setBounds(left, top, right, bottom); 39961956606818918194a38e045a8e35e7108480e5eAlan Viverette 40061956606818918194a38e045a8e35e7108480e5eAlan Viverette final Drawable background = getBackground(); 401c80ad99a33ee49d0bac994c1749ff24d243c3862Alan Viverette if (background != null) { 40261956606818918194a38e045a8e35e7108480e5eAlan Viverette background.setHotspotBounds(left, top, right, bottom); 40361956606818918194a38e045a8e35e7108480e5eAlan Viverette } 40461956606818918194a38e045a8e35e7108480e5eAlan Viverette } 40561956606818918194a38e045a8e35e7108480e5eAlan Viverette 40661956606818918194a38e045a8e35e7108480e5eAlan Viverette super.onDraw(canvas); 40761956606818918194a38e045a8e35e7108480e5eAlan Viverette 40861956606818918194a38e045a8e35e7108480e5eAlan Viverette if (buttonDrawable != null) { 409b95c336d7863e6b63e2aa8682a90dd8ae213889cAlan Viverette final int scrollX = mScrollX; 410b95c336d7863e6b63e2aa8682a90dd8ae213889cAlan Viverette final int scrollY = mScrollY; 411b95c336d7863e6b63e2aa8682a90dd8ae213889cAlan Viverette if (scrollX == 0 && scrollY == 0) { 412b95c336d7863e6b63e2aa8682a90dd8ae213889cAlan Viverette buttonDrawable.draw(canvas); 413b95c336d7863e6b63e2aa8682a90dd8ae213889cAlan Viverette } else { 414b95c336d7863e6b63e2aa8682a90dd8ae213889cAlan Viverette canvas.translate(scrollX, scrollY); 415b95c336d7863e6b63e2aa8682a90dd8ae213889cAlan Viverette buttonDrawable.draw(canvas); 416b95c336d7863e6b63e2aa8682a90dd8ae213889cAlan Viverette canvas.translate(-scrollX, -scrollY); 417b95c336d7863e6b63e2aa8682a90dd8ae213889cAlan Viverette } 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int[] onCreateDrawableState(int extraSpace) { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isChecked()) { 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mergeDrawableStates(drawableState, CHECKED_STATE_SET); 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return drawableState; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void drawableStateChanged() { 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.drawableStateChanged(); 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mButtonDrawable != null) { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] myDrawableState = getDrawableState(); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set the state of the Drawable 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mButtonDrawable.setState(myDrawableState); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidate(); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 444cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette @Override 4458de1494557cf1d00c1c3fce439138a28de7fbd61Alan Viverette public void drawableHotspotChanged(float x, float y) { 4468de1494557cf1d00c1c3fce439138a28de7fbd61Alan Viverette super.drawableHotspotChanged(x, y); 447cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette 448cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette if (mButtonDrawable != null) { 449cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette mButtonDrawable.setHotspot(x, y); 450cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette } 451cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette } 452cebc6bab51d9c77db8f346c1390169eabac4f27dAlan Viverette 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean verifyDrawable(Drawable who) { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.verifyDrawable(who) || who == mButtonDrawable; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 458e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn @Override 459e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn public void jumpDrawablesToCurrentState() { 460e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn super.jumpDrawablesToCurrentState(); 461e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn if (mButtonDrawable != null) mButtonDrawable.jumpToCurrentState(); 462e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn } 463e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static class SavedState extends BaseSavedState { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean checked; 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructor called from {@link CompoundButton#onSaveInstanceState()} 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SavedState(Parcelable superState) { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(superState); 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructor called from {@link #CREATOR} 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SavedState(Parcel in) { 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(in); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checked = (Boolean)in.readValue(null); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void writeToParcel(Parcel out, int flags) { 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.writeToParcel(out, flags); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.writeValue(checked); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "CompoundButton.SavedState{" 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " checked=" + checked + "}"; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Parcelable.Creator<SavedState> CREATOR 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new Parcelable.Creator<SavedState>() { 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SavedState createFromParcel(Parcel in) { 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new SavedState(in); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SavedState[] newArray(int size) { 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new SavedState[size]; 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Parcelable onSaveInstanceState() { 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Parcelable superState = super.onSaveInstanceState(); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SavedState ss = new SavedState(superState); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ss.checked = isChecked(); 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ss; 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onRestoreInstanceState(Parcelable state) { 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SavedState ss = (SavedState) state; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onRestoreInstanceState(ss.getSuperState()); 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setChecked(ss.checked); 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 526