blob: 3213a34e28f1a91145cd9ed7dfa1ea9a45851707 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
Alan Viverette6a394f42015-02-12 15:03:22 -080019import android.annotation.DrawableRes;
Siva Velusamy94a6d152015-05-05 15:07:00 -070020import android.annotation.NonNull;
Alan Viverette91174362014-06-17 14:51:45 -070021import android.annotation.Nullable;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.content.Context;
Alan Viverette91174362014-06-17 14:51:45 -070023import android.content.res.ColorStateList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.res.TypedArray;
25import android.graphics.Canvas;
Aurimas Liutikas99441c52016-10-11 16:48:32 -070026import android.graphics.PorterDuff;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.graphics.drawable.Drawable;
28import android.os.Parcel;
29import android.os.Parcelable;
30import android.util.AttributeSet;
31import android.view.Gravity;
Alan Viveretted4e77902014-10-27 17:50:51 -070032import android.view.SoundEffectConstants;
Steve Zeigler7a367882010-02-23 16:39:08 -080033import android.view.ViewDebug;
Aurimas Liutikas99441c52016-10-11 16:48:32 -070034import android.view.ViewHierarchyEncoder;
Jean-Baptiste Querucf4550c2009-07-21 11:16:54 -070035import android.view.accessibility.AccessibilityEvent;
Svetoslav Ganov13774d22011-06-15 15:29:51 -070036import android.view.accessibility.AccessibilityNodeInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037
Aurimas Liutikas99441c52016-10-11 16:48:32 -070038import com.android.internal.R;
39
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040/**
41 * <p>
42 * A button with two states, checked and unchecked. When the button is pressed
43 * or clicked, the state changes automatically.
44 * </p>
45 *
46 * <p><strong>XML attributes</strong></p>
47 * <p>
48 * See {@link android.R.styleable#CompoundButton
49 * CompoundButton Attributes}, {@link android.R.styleable#Button Button
50 * Attributes}, {@link android.R.styleable#TextView TextView Attributes}, {@link
51 * android.R.styleable#View View Attributes}
52 * </p>
53 */
54public abstract class CompoundButton extends Button implements Checkable {
55 private boolean mChecked;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 private boolean mBroadcasting;
Alan Viverette91174362014-06-17 14:51:45 -070057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 private Drawable mButtonDrawable;
Alan Viverettea4264452014-07-28 16:02:55 -070059 private ColorStateList mButtonTintList = null;
Alan Viveretteb56f5d22014-09-14 15:48:50 -070060 private PorterDuff.Mode mButtonTintMode = null;
Alan Viverette91174362014-06-17 14:51:45 -070061 private boolean mHasButtonTint = false;
Alan Viveretteb56f5d22014-09-14 15:48:50 -070062 private boolean mHasButtonTintMode = false;
Alan Viverette91174362014-06-17 14:51:45 -070063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 private OnCheckedChangeListener mOnCheckedChangeListener;
65 private OnCheckedChangeListener mOnCheckedChangeWidgetListener;
66
67 private static final int[] CHECKED_STATE_SET = {
68 R.attr.state_checked
69 };
70
71 public CompoundButton(Context context) {
72 this(context, null);
73 }
74
75 public CompoundButton(Context context, AttributeSet attrs) {
76 this(context, attrs, 0);
77 }
78
Alan Viverette617feb92013-09-09 18:09:13 -070079 public CompoundButton(Context context, AttributeSet attrs, int defStyleAttr) {
80 this(context, attrs, defStyleAttr, 0);
81 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082
Alan Viverette617feb92013-09-09 18:09:13 -070083 public CompoundButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
84 super(context, attrs, defStyleAttr, defStyleRes);
85
86 final TypedArray a = context.obtainStyledAttributes(
87 attrs, com.android.internal.R.styleable.CompoundButton, defStyleAttr, defStyleRes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088
Alan Viverette91174362014-06-17 14:51:45 -070089 final Drawable d = a.getDrawable(com.android.internal.R.styleable.CompoundButton_button);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 if (d != null) {
91 setButtonDrawable(d);
92 }
93
Alan Viveretteb56f5d22014-09-14 15:48:50 -070094 if (a.hasValue(R.styleable.CompoundButton_buttonTintMode)) {
95 mButtonTintMode = Drawable.parseTintMode(a.getInt(
96 R.styleable.CompoundButton_buttonTintMode, -1), mButtonTintMode);
97 mHasButtonTintMode = true;
98 }
Alan Viverette4f64c042014-07-21 17:49:13 -070099
Alan Viverette91174362014-06-17 14:51:45 -0700100 if (a.hasValue(R.styleable.CompoundButton_buttonTint)) {
Alan Viverettea4264452014-07-28 16:02:55 -0700101 mButtonTintList = a.getColorStateList(R.styleable.CompoundButton_buttonTint);
Alan Viverette91174362014-06-17 14:51:45 -0700102 mHasButtonTint = true;
Alan Viverette91174362014-06-17 14:51:45 -0700103 }
104
105 final boolean checked = a.getBoolean(
106 com.android.internal.R.styleable.CompoundButton_checked, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 setChecked(checked);
108
109 a.recycle();
Alan Viveretteb56f5d22014-09-14 15:48:50 -0700110
111 applyButtonTint();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 }
113
114 public void toggle() {
115 setChecked(!mChecked);
116 }
117
118 @Override
119 public boolean performClick() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 toggle();
Alan Viveretted4e77902014-10-27 17:50:51 -0700121
122 final boolean handled = super.performClick();
123 if (!handled) {
124 // View only makes a sound effect if the onClickListener was
125 // called, so we'll need to make one here instead.
126 playSoundEffect(SoundEffectConstants.CLICK);
127 }
128
129 return handled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 }
131
Steve Zeigler7a367882010-02-23 16:39:08 -0800132 @ViewDebug.ExportedProperty
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 public boolean isChecked() {
134 return mChecked;
135 }
136
137 /**
138 * <p>Changes the checked state of this button.</p>
139 *
140 * @param checked true to check the button, false to uncheck it
141 */
142 public void setChecked(boolean checked) {
143 if (mChecked != checked) {
144 mChecked = checked;
145 refreshDrawableState();
Alan Viverette77e9a282013-09-12 17:16:09 -0700146 notifyViewAccessibilityStateChangedIfNeeded(
147 AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148
149 // Avoid infinite recursions if setChecked() is called from a listener
150 if (mBroadcasting) {
151 return;
152 }
153
154 mBroadcasting = true;
155 if (mOnCheckedChangeListener != null) {
156 mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
157 }
158 if (mOnCheckedChangeWidgetListener != null) {
159 mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);
160 }
Jean-Baptiste Querucf4550c2009-07-21 11:16:54 -0700161
Aurimas Liutikas99441c52016-10-11 16:48:32 -0700162 mBroadcasting = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 }
164 }
165
166 /**
167 * Register a callback to be invoked when the checked state of this button
168 * changes.
169 *
170 * @param listener the callback to call on checked state change
171 */
Jason Longacdaaea502016-12-01 22:54:37 -0800172 public void setOnCheckedChangeListener(@Nullable OnCheckedChangeListener listener) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 mOnCheckedChangeListener = listener;
174 }
175
176 /**
177 * Register a callback to be invoked when the checked state of this button
178 * changes. This callback is used for internal purpose only.
179 *
180 * @param listener the callback to call on checked state change
181 * @hide
182 */
183 void setOnCheckedChangeWidgetListener(OnCheckedChangeListener listener) {
184 mOnCheckedChangeWidgetListener = listener;
185 }
186
187 /**
188 * Interface definition for a callback to be invoked when the checked state
189 * of a compound button changed.
190 */
191 public static interface OnCheckedChangeListener {
192 /**
193 * Called when the checked state of a compound button has changed.
194 *
195 * @param buttonView The compound button view whose state has changed.
196 * @param isChecked The new checked state of buttonView.
197 */
198 void onCheckedChanged(CompoundButton buttonView, boolean isChecked);
199 }
200
201 /**
Alan Viverette6a394f42015-02-12 15:03:22 -0800202 * Sets a drawable as the compound button image given its resource
203 * identifier.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 *
Alan Viverette6a394f42015-02-12 15:03:22 -0800205 * @param resId the resource identifier of the drawable
206 * @attr ref android.R.styleable#CompoundButton_button
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 */
Alan Viverette6a394f42015-02-12 15:03:22 -0800208 public void setButtonDrawable(@DrawableRes int resId) {
209 final Drawable d;
210 if (resId != 0) {
211 d = getContext().getDrawable(resId);
212 } else {
213 d = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 }
215 setButtonDrawable(d);
216 }
217
218 /**
Alan Viverette6a394f42015-02-12 15:03:22 -0800219 * Sets a drawable as the compound button image.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 *
Alan Viverette6a394f42015-02-12 15:03:22 -0800221 * @param drawable the drawable to set
222 * @attr ref android.R.styleable#CompoundButton_button
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 */
Alan Viverette6a394f42015-02-12 15:03:22 -0800224 public void setButtonDrawable(@Nullable Drawable drawable) {
225 if (mButtonDrawable != drawable) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 if (mButtonDrawable != null) {
227 mButtonDrawable.setCallback(null);
228 unscheduleDrawable(mButtonDrawable);
229 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230
Alan Viverette6a394f42015-02-12 15:03:22 -0800231 mButtonDrawable = drawable;
Alan Viverette91174362014-06-17 14:51:45 -0700232
Alan Viverette6a394f42015-02-12 15:03:22 -0800233 if (drawable != null) {
234 drawable.setCallback(this);
235 drawable.setLayoutDirection(getLayoutDirection());
236 if (drawable.isStateful()) {
237 drawable.setState(getDrawableState());
Alan Viverette91174362014-06-17 14:51:45 -0700238 }
Alan Viverette6a394f42015-02-12 15:03:22 -0800239 drawable.setVisible(getVisibility() == VISIBLE, false);
240 setMinHeight(drawable.getIntrinsicHeight());
Alan Viverette91174362014-06-17 14:51:45 -0700241 applyButtonTint();
242 }
243 }
244 }
245
246 /**
Doris Liu3380e692015-06-30 11:26:47 -0700247 * @hide
248 */
249 @Override
250 public void onResolveDrawables(@ResolvedLayoutDir int layoutDirection) {
251 super.onResolveDrawables(layoutDirection);
252 if (mButtonDrawable != null) {
253 mButtonDrawable.setLayoutDirection(layoutDirection);
254 }
255 }
256
257 /**
Alan Viverette6a394f42015-02-12 15:03:22 -0800258 * @return the drawable used as the compound button image
259 * @see #setButtonDrawable(Drawable)
260 * @see #setButtonDrawable(int)
261 */
262 @Nullable
263 public Drawable getButtonDrawable() {
264 return mButtonDrawable;
265 }
266
267 /**
Alan Viverette91174362014-06-17 14:51:45 -0700268 * Applies a tint to the button drawable. Does not modify the current tint
Alan Viveretteb56f5d22014-09-14 15:48:50 -0700269 * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
Alan Viverette91174362014-06-17 14:51:45 -0700270 * <p>
271 * Subsequent calls to {@link #setButtonDrawable(Drawable)} will
272 * automatically mutate the drawable and apply the specified tint and tint
273 * mode using
Alan Viverettea4264452014-07-28 16:02:55 -0700274 * {@link Drawable#setTintList(ColorStateList)}.
Alan Viverette91174362014-06-17 14:51:45 -0700275 *
276 * @param tint the tint to apply, may be {@code null} to clear tint
277 *
278 * @attr ref android.R.styleable#CompoundButton_buttonTint
Alan Viverettea4264452014-07-28 16:02:55 -0700279 * @see #setButtonTintList(ColorStateList)
280 * @see Drawable#setTintList(ColorStateList)
Alan Viverette91174362014-06-17 14:51:45 -0700281 */
Alan Viverettea4264452014-07-28 16:02:55 -0700282 public void setButtonTintList(@Nullable ColorStateList tint) {
283 mButtonTintList = tint;
Alan Viverette4f64c042014-07-21 17:49:13 -0700284 mHasButtonTint = true;
285
286 applyButtonTint();
Alan Viverette91174362014-06-17 14:51:45 -0700287 }
288
289 /**
290 * @return the tint applied to the button drawable
291 * @attr ref android.R.styleable#CompoundButton_buttonTint
Alan Viverettea4264452014-07-28 16:02:55 -0700292 * @see #setButtonTintList(ColorStateList)
Alan Viverette91174362014-06-17 14:51:45 -0700293 */
294 @Nullable
Alan Viverettea4264452014-07-28 16:02:55 -0700295 public ColorStateList getButtonTintList() {
296 return mButtonTintList;
Alan Viverette91174362014-06-17 14:51:45 -0700297 }
298
299 /**
300 * Specifies the blending mode used to apply the tint specified by
Alan Viverettea4264452014-07-28 16:02:55 -0700301 * {@link #setButtonTintList(ColorStateList)}} to the button drawable. The
Alan Viveretteb56f5d22014-09-14 15:48:50 -0700302 * default mode is {@link PorterDuff.Mode#SRC_IN}.
Alan Viverette91174362014-06-17 14:51:45 -0700303 *
304 * @param tintMode the blending mode used to apply the tint, may be
305 * {@code null} to clear tint
306 * @attr ref android.R.styleable#CompoundButton_buttonTintMode
Alan Viverette4f64c042014-07-21 17:49:13 -0700307 * @see #getButtonTintMode()
Alan Viverettea4264452014-07-28 16:02:55 -0700308 * @see Drawable#setTintMode(PorterDuff.Mode)
Alan Viverette91174362014-06-17 14:51:45 -0700309 */
310 public void setButtonTintMode(@Nullable PorterDuff.Mode tintMode) {
Alan Viverette4f64c042014-07-21 17:49:13 -0700311 mButtonTintMode = tintMode;
Alan Viveretteb56f5d22014-09-14 15:48:50 -0700312 mHasButtonTintMode = true;
Alan Viverette4f64c042014-07-21 17:49:13 -0700313
314 applyButtonTint();
Alan Viverette91174362014-06-17 14:51:45 -0700315 }
316
317 /**
318 * @return the blending mode used to apply the tint to the button drawable
319 * @attr ref android.R.styleable#CompoundButton_buttonTintMode
Alan Viverette4f64c042014-07-21 17:49:13 -0700320 * @see #setButtonTintMode(PorterDuff.Mode)
Alan Viverette91174362014-06-17 14:51:45 -0700321 */
322 @Nullable
323 public PorterDuff.Mode getButtonTintMode() {
324 return mButtonTintMode;
325 }
326
327 private void applyButtonTint() {
Alan Viveretteb56f5d22014-09-14 15:48:50 -0700328 if (mButtonDrawable != null && (mHasButtonTint || mHasButtonTintMode)) {
Alan Viverette91174362014-06-17 14:51:45 -0700329 mButtonDrawable = mButtonDrawable.mutate();
Alan Viveretteb56f5d22014-09-14 15:48:50 -0700330
331 if (mHasButtonTint) {
332 mButtonDrawable.setTintList(mButtonTintList);
333 }
334
335 if (mHasButtonTintMode) {
336 mButtonDrawable.setTintMode(mButtonTintMode);
337 }
Alan Viveretted5133792014-10-28 14:41:36 -0700338
339 // The drawable (or one of its children) may not have been
340 // stateful before applying the tint, so let's try again.
341 if (mButtonDrawable.isStateful()) {
342 mButtonDrawable.setState(getDrawableState());
343 }
Alan Viverette91174362014-06-17 14:51:45 -0700344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345 }
346
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800347 @Override
348 public CharSequence getAccessibilityClassName() {
349 return CompoundButton.class.getName();
350 }
351
Alan Viverettea54956a2015-01-07 16:05:02 -0800352 /** @hide */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800353 @Override
Alan Viverettea54956a2015-01-07 16:05:02 -0800354 public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
355 super.onInitializeAccessibilityEventInternal(event);
Svetoslav Ganov736c2752011-04-22 18:30:36 -0700356 event.setChecked(mChecked);
Jean-Baptiste Querucf4550c2009-07-21 11:16:54 -0700357 }
358
Alan Viverettea54956a2015-01-07 16:05:02 -0800359 /** @hide */
Jean-Baptiste Querucf4550c2009-07-21 11:16:54 -0700360 @Override
Alan Viverettea54956a2015-01-07 16:05:02 -0800361 public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
362 super.onInitializeAccessibilityNodeInfoInternal(info);
Svetoslav Ganov0f55cc32011-07-17 10:51:49 -0700363 info.setCheckable(true);
Svetoslav Ganov13774d22011-06-15 15:29:51 -0700364 info.setChecked(mChecked);
365 }
366
367 @Override
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700368 public int getCompoundPaddingLeft() {
369 int padding = super.getCompoundPaddingLeft();
370 if (!isLayoutRtl()) {
371 final Drawable buttonDrawable = mButtonDrawable;
372 if (buttonDrawable != null) {
373 padding += buttonDrawable.getIntrinsicWidth();
374 }
375 }
376 return padding;
377 }
378
379 @Override
380 public int getCompoundPaddingRight() {
381 int padding = super.getCompoundPaddingRight();
382 if (isLayoutRtl()) {
383 final Drawable buttonDrawable = mButtonDrawable;
384 if (buttonDrawable != null) {
385 padding += buttonDrawable.getIntrinsicWidth();
386 }
387 }
388 return padding;
389 }
390
Fabrice Di Megliob878ddb2012-11-27 17:44:33 -0800391 /**
392 * @hide
393 */
394 @Override
395 public int getHorizontalOffsetForDrawables() {
396 final Drawable buttonDrawable = mButtonDrawable;
397 return (buttonDrawable != null) ? buttonDrawable.getIntrinsicWidth() : 0;
398 }
399
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700400 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 protected void onDraw(Canvas canvas) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 final Drawable buttonDrawable = mButtonDrawable;
403 if (buttonDrawable != null) {
404 final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700405 final int drawableHeight = buttonDrawable.getIntrinsicHeight();
406 final int drawableWidth = buttonDrawable.getIntrinsicWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407
Alan Viverette61956602014-04-22 19:07:06 -0700408 final int top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 switch (verticalGravity) {
410 case Gravity.BOTTOM:
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700411 top = getHeight() - drawableHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 break;
413 case Gravity.CENTER_VERTICAL:
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700414 top = (getHeight() - drawableHeight) / 2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 break;
Alan Viverette61956602014-04-22 19:07:06 -0700416 default:
417 top = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 }
Alan Viverette61956602014-04-22 19:07:06 -0700419 final int bottom = top + drawableHeight;
420 final int left = isLayoutRtl() ? getWidth() - drawableWidth : 0;
421 final int right = isLayoutRtl() ? getWidth() : drawableWidth;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700423 buttonDrawable.setBounds(left, top, right, bottom);
Alan Viverette61956602014-04-22 19:07:06 -0700424
425 final Drawable background = getBackground();
Alan Viverettec80ad992014-05-19 15:46:17 -0700426 if (background != null) {
Alan Viverette61956602014-04-22 19:07:06 -0700427 background.setHotspotBounds(left, top, right, bottom);
428 }
429 }
430
431 super.onDraw(canvas);
432
433 if (buttonDrawable != null) {
Alan Viveretteb95c3362014-10-17 17:19:12 -0700434 final int scrollX = mScrollX;
435 final int scrollY = mScrollY;
436 if (scrollX == 0 && scrollY == 0) {
437 buttonDrawable.draw(canvas);
438 } else {
439 canvas.translate(scrollX, scrollY);
440 buttonDrawable.draw(canvas);
441 canvas.translate(-scrollX, -scrollY);
442 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 }
444 }
445
446 @Override
447 protected int[] onCreateDrawableState(int extraSpace) {
448 final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
449 if (isChecked()) {
450 mergeDrawableStates(drawableState, CHECKED_STATE_SET);
451 }
452 return drawableState;
453 }
454
455 @Override
456 protected void drawableStateChanged() {
457 super.drawableStateChanged();
Alan Viverettead0020f2015-09-04 10:10:42 -0400458
459 final Drawable buttonDrawable = mButtonDrawable;
460 if (buttonDrawable != null && buttonDrawable.isStateful()
461 && buttonDrawable.setState(getDrawableState())) {
462 invalidateDrawable(buttonDrawable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 }
464 }
465
Alan Viverettecebc6ba2014-06-13 15:52:13 -0700466 @Override
Alan Viverette8de14942014-06-18 18:05:15 -0700467 public void drawableHotspotChanged(float x, float y) {
468 super.drawableHotspotChanged(x, y);
Alan Viverettecebc6ba2014-06-13 15:52:13 -0700469
470 if (mButtonDrawable != null) {
471 mButtonDrawable.setHotspot(x, y);
472 }
473 }
474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 @Override
Alan Viverettef6d87ec2016-03-11 10:09:14 -0500476 protected boolean verifyDrawable(@NonNull Drawable who) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800477 return super.verifyDrawable(who) || who == mButtonDrawable;
478 }
479
Dianne Hackborne2136772010-11-04 15:08:59 -0700480 @Override
481 public void jumpDrawablesToCurrentState() {
482 super.jumpDrawablesToCurrentState();
483 if (mButtonDrawable != null) mButtonDrawable.jumpToCurrentState();
484 }
485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 static class SavedState extends BaseSavedState {
487 boolean checked;
488
489 /**
490 * Constructor called from {@link CompoundButton#onSaveInstanceState()}
491 */
492 SavedState(Parcelable superState) {
493 super(superState);
494 }
Aurimas Liutikas99441c52016-10-11 16:48:32 -0700495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 /**
497 * Constructor called from {@link #CREATOR}
498 */
499 private SavedState(Parcel in) {
500 super(in);
501 checked = (Boolean)in.readValue(null);
502 }
503
504 @Override
505 public void writeToParcel(Parcel out, int flags) {
506 super.writeToParcel(out, flags);
507 out.writeValue(checked);
508 }
509
510 @Override
511 public String toString() {
512 return "CompoundButton.SavedState{"
513 + Integer.toHexString(System.identityHashCode(this))
514 + " checked=" + checked + "}";
515 }
516
517 public static final Parcelable.Creator<SavedState> CREATOR
518 = new Parcelable.Creator<SavedState>() {
519 public SavedState createFromParcel(Parcel in) {
520 return new SavedState(in);
521 }
522
523 public SavedState[] newArray(int size) {
524 return new SavedState[size];
525 }
526 };
527 }
528
529 @Override
530 public Parcelable onSaveInstanceState() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 Parcelable superState = super.onSaveInstanceState();
532
533 SavedState ss = new SavedState(superState);
534
535 ss.checked = isChecked();
536 return ss;
537 }
538
539 @Override
540 public void onRestoreInstanceState(Parcelable state) {
541 SavedState ss = (SavedState) state;
Siva Velusamy94a6d152015-05-05 15:07:00 -0700542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 super.onRestoreInstanceState(ss.getSuperState());
544 setChecked(ss.checked);
545 requestLayout();
546 }
Siva Velusamy94a6d152015-05-05 15:07:00 -0700547
548 /** @hide */
549 @Override
550 protected void encodeProperties(@NonNull ViewHierarchyEncoder stream) {
551 super.encodeProperties(stream);
552 stream.addProperty("checked", isChecked());
553 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554}