blob: 41a3915e21aedc0e3f152949809c72aeaf27ba99 [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 Viverette91174362014-06-17 14:51:45 -070019import android.annotation.Nullable;
20import android.graphics.PorterDuff;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import com.android.internal.R;
22
23import android.content.Context;
Alan Viverette91174362014-06-17 14:51:45 -070024import android.content.res.ColorStateList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.content.res.TypedArray;
26import android.graphics.Canvas;
27import 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;
Jean-Baptiste Querucf4550c2009-07-21 11:16:54 -070034import android.view.accessibility.AccessibilityEvent;
Svetoslav Ganov13774d22011-06-15 15:29:51 -070035import android.view.accessibility.AccessibilityNodeInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036
37/**
38 * <p>
39 * A button with two states, checked and unchecked. When the button is pressed
40 * or clicked, the state changes automatically.
41 * </p>
42 *
43 * <p><strong>XML attributes</strong></p>
44 * <p>
45 * See {@link android.R.styleable#CompoundButton
46 * CompoundButton Attributes}, {@link android.R.styleable#Button Button
47 * Attributes}, {@link android.R.styleable#TextView TextView Attributes}, {@link
48 * android.R.styleable#View View Attributes}
49 * </p>
50 */
51public abstract class CompoundButton extends Button implements Checkable {
52 private boolean mChecked;
53 private int mButtonResource;
54 private boolean mBroadcasting;
Alan Viverette91174362014-06-17 14:51:45 -070055
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 private Drawable mButtonDrawable;
Alan Viverettea4264452014-07-28 16:02:55 -070057 private ColorStateList mButtonTintList = null;
Alan Viveretteb56f5d22014-09-14 15:48:50 -070058 private PorterDuff.Mode mButtonTintMode = null;
Alan Viverette91174362014-06-17 14:51:45 -070059 private boolean mHasButtonTint = false;
Alan Viveretteb56f5d22014-09-14 15:48:50 -070060 private boolean mHasButtonTintMode = false;
Alan Viverette91174362014-06-17 14:51:45 -070061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 private OnCheckedChangeListener mOnCheckedChangeListener;
63 private OnCheckedChangeListener mOnCheckedChangeWidgetListener;
64
65 private static final int[] CHECKED_STATE_SET = {
66 R.attr.state_checked
67 };
68
69 public CompoundButton(Context context) {
70 this(context, null);
71 }
72
73 public CompoundButton(Context context, AttributeSet attrs) {
74 this(context, attrs, 0);
75 }
76
Alan Viverette617feb92013-09-09 18:09:13 -070077 public CompoundButton(Context context, AttributeSet attrs, int defStyleAttr) {
78 this(context, attrs, defStyleAttr, 0);
79 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080
Alan Viverette617feb92013-09-09 18:09:13 -070081 public CompoundButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
82 super(context, attrs, defStyleAttr, defStyleRes);
83
84 final TypedArray a = context.obtainStyledAttributes(
85 attrs, com.android.internal.R.styleable.CompoundButton, defStyleAttr, defStyleRes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086
Alan Viverette91174362014-06-17 14:51:45 -070087 final Drawable d = a.getDrawable(com.android.internal.R.styleable.CompoundButton_button);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 if (d != null) {
89 setButtonDrawable(d);
90 }
91
Alan Viveretteb56f5d22014-09-14 15:48:50 -070092 if (a.hasValue(R.styleable.CompoundButton_buttonTintMode)) {
93 mButtonTintMode = Drawable.parseTintMode(a.getInt(
94 R.styleable.CompoundButton_buttonTintMode, -1), mButtonTintMode);
95 mHasButtonTintMode = true;
96 }
Alan Viverette4f64c042014-07-21 17:49:13 -070097
Alan Viverette91174362014-06-17 14:51:45 -070098 if (a.hasValue(R.styleable.CompoundButton_buttonTint)) {
Alan Viverettea4264452014-07-28 16:02:55 -070099 mButtonTintList = a.getColorStateList(R.styleable.CompoundButton_buttonTint);
Alan Viverette91174362014-06-17 14:51:45 -0700100 mHasButtonTint = true;
Alan Viverette91174362014-06-17 14:51:45 -0700101 }
102
103 final boolean checked = a.getBoolean(
104 com.android.internal.R.styleable.CompoundButton_checked, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 setChecked(checked);
106
107 a.recycle();
Alan Viveretteb56f5d22014-09-14 15:48:50 -0700108
109 applyButtonTint();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 }
111
112 public void toggle() {
113 setChecked(!mChecked);
114 }
115
116 @Override
117 public boolean performClick() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118 toggle();
Alan Viveretted4e77902014-10-27 17:50:51 -0700119
120 final boolean handled = super.performClick();
121 if (!handled) {
122 // View only makes a sound effect if the onClickListener was
123 // called, so we'll need to make one here instead.
124 playSoundEffect(SoundEffectConstants.CLICK);
125 }
126
127 return handled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 }
129
Steve Zeigler7a367882010-02-23 16:39:08 -0800130 @ViewDebug.ExportedProperty
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 public boolean isChecked() {
132 return mChecked;
133 }
134
135 /**
136 * <p>Changes the checked state of this button.</p>
137 *
138 * @param checked true to check the button, false to uncheck it
139 */
140 public void setChecked(boolean checked) {
141 if (mChecked != checked) {
142 mChecked = checked;
143 refreshDrawableState();
Alan Viverette77e9a282013-09-12 17:16:09 -0700144 notifyViewAccessibilityStateChangedIfNeeded(
145 AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146
147 // Avoid infinite recursions if setChecked() is called from a listener
148 if (mBroadcasting) {
149 return;
150 }
151
152 mBroadcasting = true;
153 if (mOnCheckedChangeListener != null) {
154 mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
155 }
156 if (mOnCheckedChangeWidgetListener != null) {
157 mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);
158 }
Jean-Baptiste Querucf4550c2009-07-21 11:16:54 -0700159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 mBroadcasting = false;
161 }
162 }
163
164 /**
165 * Register a callback to be invoked when the checked state of this button
166 * changes.
167 *
168 * @param listener the callback to call on checked state change
169 */
170 public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
171 mOnCheckedChangeListener = listener;
172 }
173
174 /**
175 * Register a callback to be invoked when the checked state of this button
176 * changes. This callback is used for internal purpose only.
177 *
178 * @param listener the callback to call on checked state change
179 * @hide
180 */
181 void setOnCheckedChangeWidgetListener(OnCheckedChangeListener listener) {
182 mOnCheckedChangeWidgetListener = listener;
183 }
184
185 /**
186 * Interface definition for a callback to be invoked when the checked state
187 * of a compound button changed.
188 */
189 public static interface OnCheckedChangeListener {
190 /**
191 * Called when the checked state of a compound button has changed.
192 *
193 * @param buttonView The compound button view whose state has changed.
194 * @param isChecked The new checked state of buttonView.
195 */
196 void onCheckedChanged(CompoundButton buttonView, boolean isChecked);
197 }
198
199 /**
Alan Viverette91174362014-06-17 14:51:45 -0700200 * Set the button graphic to a given Drawable, identified by its resource
201 * id.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 *
Alan Viverette91174362014-06-17 14:51:45 -0700203 * @param resid the resource id of the drawable to use as the button
204 * graphic
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 */
206 public void setButtonDrawable(int resid) {
207 if (resid != 0 && resid == mButtonResource) {
208 return;
209 }
210
211 mButtonResource = resid;
212
213 Drawable d = null;
214 if (mButtonResource != 0) {
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800215 d = getContext().getDrawable(mButtonResource);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 }
217 setButtonDrawable(d);
218 }
219
220 /**
Alan Viverette91174362014-06-17 14:51:45 -0700221 * Set the button graphic to a given Drawable
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222 *
Alan Viverette91174362014-06-17 14:51:45 -0700223 * @param d The Drawable to use as the button graphic
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 */
225 public void setButtonDrawable(Drawable d) {
Alan Viverette91174362014-06-17 14:51:45 -0700226 if (mButtonDrawable != d) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 if (mButtonDrawable != null) {
228 mButtonDrawable.setCallback(null);
229 unscheduleDrawable(mButtonDrawable);
230 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231
Alan Viverette91174362014-06-17 14:51:45 -0700232 mButtonDrawable = d;
233
234 if (d != null) {
235 d.setCallback(this);
236 d.setLayoutDirection(getLayoutDirection());
237 if (d.isStateful()) {
238 d.setState(getDrawableState());
239 }
240 d.setVisible(getVisibility() == VISIBLE, false);
241 setMinHeight(d.getIntrinsicHeight());
242 applyButtonTint();
243 }
244 }
245 }
246
247 /**
Alan Viverette91174362014-06-17 14:51:45 -0700248 * Applies a tint to the button drawable. Does not modify the current tint
Alan Viveretteb56f5d22014-09-14 15:48:50 -0700249 * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
Alan Viverette91174362014-06-17 14:51:45 -0700250 * <p>
251 * Subsequent calls to {@link #setButtonDrawable(Drawable)} will
252 * automatically mutate the drawable and apply the specified tint and tint
253 * mode using
Alan Viverettea4264452014-07-28 16:02:55 -0700254 * {@link Drawable#setTintList(ColorStateList)}.
Alan Viverette91174362014-06-17 14:51:45 -0700255 *
256 * @param tint the tint to apply, may be {@code null} to clear tint
257 *
258 * @attr ref android.R.styleable#CompoundButton_buttonTint
Alan Viverettea4264452014-07-28 16:02:55 -0700259 * @see #setButtonTintList(ColorStateList)
260 * @see Drawable#setTintList(ColorStateList)
Alan Viverette91174362014-06-17 14:51:45 -0700261 */
Alan Viverettea4264452014-07-28 16:02:55 -0700262 public void setButtonTintList(@Nullable ColorStateList tint) {
263 mButtonTintList = tint;
Alan Viverette4f64c042014-07-21 17:49:13 -0700264 mHasButtonTint = true;
265
266 applyButtonTint();
Alan Viverette91174362014-06-17 14:51:45 -0700267 }
268
269 /**
270 * @return the tint applied to the button drawable
271 * @attr ref android.R.styleable#CompoundButton_buttonTint
Alan Viverettea4264452014-07-28 16:02:55 -0700272 * @see #setButtonTintList(ColorStateList)
Alan Viverette91174362014-06-17 14:51:45 -0700273 */
274 @Nullable
Alan Viverettea4264452014-07-28 16:02:55 -0700275 public ColorStateList getButtonTintList() {
276 return mButtonTintList;
Alan Viverette91174362014-06-17 14:51:45 -0700277 }
278
279 /**
280 * Specifies the blending mode used to apply the tint specified by
Alan Viverettea4264452014-07-28 16:02:55 -0700281 * {@link #setButtonTintList(ColorStateList)}} to the button drawable. The
Alan Viveretteb56f5d22014-09-14 15:48:50 -0700282 * default mode is {@link PorterDuff.Mode#SRC_IN}.
Alan Viverette91174362014-06-17 14:51:45 -0700283 *
284 * @param tintMode the blending mode used to apply the tint, may be
285 * {@code null} to clear tint
286 * @attr ref android.R.styleable#CompoundButton_buttonTintMode
Alan Viverette4f64c042014-07-21 17:49:13 -0700287 * @see #getButtonTintMode()
Alan Viverettea4264452014-07-28 16:02:55 -0700288 * @see Drawable#setTintMode(PorterDuff.Mode)
Alan Viverette91174362014-06-17 14:51:45 -0700289 */
290 public void setButtonTintMode(@Nullable PorterDuff.Mode tintMode) {
Alan Viverette4f64c042014-07-21 17:49:13 -0700291 mButtonTintMode = tintMode;
Alan Viveretteb56f5d22014-09-14 15:48:50 -0700292 mHasButtonTintMode = true;
Alan Viverette4f64c042014-07-21 17:49:13 -0700293
294 applyButtonTint();
Alan Viverette91174362014-06-17 14:51:45 -0700295 }
296
297 /**
298 * @return the blending mode used to apply the tint to the button drawable
299 * @attr ref android.R.styleable#CompoundButton_buttonTintMode
Alan Viverette4f64c042014-07-21 17:49:13 -0700300 * @see #setButtonTintMode(PorterDuff.Mode)
Alan Viverette91174362014-06-17 14:51:45 -0700301 */
302 @Nullable
303 public PorterDuff.Mode getButtonTintMode() {
304 return mButtonTintMode;
305 }
306
307 private void applyButtonTint() {
Alan Viveretteb56f5d22014-09-14 15:48:50 -0700308 if (mButtonDrawable != null && (mHasButtonTint || mHasButtonTintMode)) {
Alan Viverette91174362014-06-17 14:51:45 -0700309 mButtonDrawable = mButtonDrawable.mutate();
Alan Viveretteb56f5d22014-09-14 15:48:50 -0700310
311 if (mHasButtonTint) {
312 mButtonDrawable.setTintList(mButtonTintList);
313 }
314
315 if (mHasButtonTintMode) {
316 mButtonDrawable.setTintMode(mButtonTintMode);
317 }
Alan Viveretted5133792014-10-28 14:41:36 -0700318
319 // The drawable (or one of its children) may not have been
320 // stateful before applying the tint, so let's try again.
321 if (mButtonDrawable.isStateful()) {
322 mButtonDrawable.setState(getDrawableState());
323 }
Alan Viverette91174362014-06-17 14:51:45 -0700324 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 }
326
Alan Viverettea54956a2015-01-07 16:05:02 -0800327 /** @hide */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 @Override
Alan Viverettea54956a2015-01-07 16:05:02 -0800329 public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
330 super.onInitializeAccessibilityEventInternal(event);
Svetoslav Ganov8a78fd42012-01-17 14:36:46 -0800331 event.setClassName(CompoundButton.class.getName());
Svetoslav Ganov736c2752011-04-22 18:30:36 -0700332 event.setChecked(mChecked);
Jean-Baptiste Querucf4550c2009-07-21 11:16:54 -0700333 }
334
Alan Viverettea54956a2015-01-07 16:05:02 -0800335 /** @hide */
Jean-Baptiste Querucf4550c2009-07-21 11:16:54 -0700336 @Override
Alan Viverettea54956a2015-01-07 16:05:02 -0800337 public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
338 super.onInitializeAccessibilityNodeInfoInternal(info);
Svetoslav Ganov8a78fd42012-01-17 14:36:46 -0800339 info.setClassName(CompoundButton.class.getName());
Svetoslav Ganov0f55cc32011-07-17 10:51:49 -0700340 info.setCheckable(true);
Svetoslav Ganov13774d22011-06-15 15:29:51 -0700341 info.setChecked(mChecked);
342 }
343
344 @Override
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700345 public int getCompoundPaddingLeft() {
346 int padding = super.getCompoundPaddingLeft();
347 if (!isLayoutRtl()) {
348 final Drawable buttonDrawable = mButtonDrawable;
349 if (buttonDrawable != null) {
350 padding += buttonDrawable.getIntrinsicWidth();
351 }
352 }
353 return padding;
354 }
355
356 @Override
357 public int getCompoundPaddingRight() {
358 int padding = super.getCompoundPaddingRight();
359 if (isLayoutRtl()) {
360 final Drawable buttonDrawable = mButtonDrawable;
361 if (buttonDrawable != null) {
362 padding += buttonDrawable.getIntrinsicWidth();
363 }
364 }
365 return padding;
366 }
367
Fabrice Di Megliob878ddb2012-11-27 17:44:33 -0800368 /**
369 * @hide
370 */
371 @Override
372 public int getHorizontalOffsetForDrawables() {
373 final Drawable buttonDrawable = mButtonDrawable;
374 return (buttonDrawable != null) ? buttonDrawable.getIntrinsicWidth() : 0;
375 }
376
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700377 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 protected void onDraw(Canvas canvas) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 final Drawable buttonDrawable = mButtonDrawable;
380 if (buttonDrawable != null) {
381 final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700382 final int drawableHeight = buttonDrawable.getIntrinsicHeight();
383 final int drawableWidth = buttonDrawable.getIntrinsicWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384
Alan Viverette61956602014-04-22 19:07:06 -0700385 final int top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 switch (verticalGravity) {
387 case Gravity.BOTTOM:
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700388 top = getHeight() - drawableHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 break;
390 case Gravity.CENTER_VERTICAL:
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700391 top = (getHeight() - drawableHeight) / 2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 break;
Alan Viverette61956602014-04-22 19:07:06 -0700393 default:
394 top = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 }
Alan Viverette61956602014-04-22 19:07:06 -0700396 final int bottom = top + drawableHeight;
397 final int left = isLayoutRtl() ? getWidth() - drawableWidth : 0;
398 final int right = isLayoutRtl() ? getWidth() : drawableWidth;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700400 buttonDrawable.setBounds(left, top, right, bottom);
Alan Viverette61956602014-04-22 19:07:06 -0700401
402 final Drawable background = getBackground();
Alan Viverettec80ad992014-05-19 15:46:17 -0700403 if (background != null) {
Alan Viverette61956602014-04-22 19:07:06 -0700404 background.setHotspotBounds(left, top, right, bottom);
405 }
406 }
407
408 super.onDraw(canvas);
409
410 if (buttonDrawable != null) {
Alan Viveretteb95c3362014-10-17 17:19:12 -0700411 final int scrollX = mScrollX;
412 final int scrollY = mScrollY;
413 if (scrollX == 0 && scrollY == 0) {
414 buttonDrawable.draw(canvas);
415 } else {
416 canvas.translate(scrollX, scrollY);
417 buttonDrawable.draw(canvas);
418 canvas.translate(-scrollX, -scrollY);
419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 }
421 }
422
423 @Override
424 protected int[] onCreateDrawableState(int extraSpace) {
425 final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
426 if (isChecked()) {
427 mergeDrawableStates(drawableState, CHECKED_STATE_SET);
428 }
429 return drawableState;
430 }
431
432 @Override
433 protected void drawableStateChanged() {
434 super.drawableStateChanged();
435
436 if (mButtonDrawable != null) {
437 int[] myDrawableState = getDrawableState();
438
439 // Set the state of the Drawable
440 mButtonDrawable.setState(myDrawableState);
441
442 invalidate();
443 }
444 }
445
Alan Viverettecebc6ba2014-06-13 15:52:13 -0700446 @Override
Alan Viverette8de14942014-06-18 18:05:15 -0700447 public void drawableHotspotChanged(float x, float y) {
448 super.drawableHotspotChanged(x, y);
Alan Viverettecebc6ba2014-06-13 15:52:13 -0700449
450 if (mButtonDrawable != null) {
451 mButtonDrawable.setHotspot(x, y);
452 }
453 }
454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 @Override
456 protected boolean verifyDrawable(Drawable who) {
457 return super.verifyDrawable(who) || who == mButtonDrawable;
458 }
459
Dianne Hackborne2136772010-11-04 15:08:59 -0700460 @Override
461 public void jumpDrawablesToCurrentState() {
462 super.jumpDrawablesToCurrentState();
463 if (mButtonDrawable != null) mButtonDrawable.jumpToCurrentState();
464 }
465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466 static class SavedState extends BaseSavedState {
467 boolean checked;
468
469 /**
470 * Constructor called from {@link CompoundButton#onSaveInstanceState()}
471 */
472 SavedState(Parcelable superState) {
473 super(superState);
474 }
475
476 /**
477 * Constructor called from {@link #CREATOR}
478 */
479 private SavedState(Parcel in) {
480 super(in);
481 checked = (Boolean)in.readValue(null);
482 }
483
484 @Override
485 public void writeToParcel(Parcel out, int flags) {
486 super.writeToParcel(out, flags);
487 out.writeValue(checked);
488 }
489
490 @Override
491 public String toString() {
492 return "CompoundButton.SavedState{"
493 + Integer.toHexString(System.identityHashCode(this))
494 + " checked=" + checked + "}";
495 }
496
497 public static final Parcelable.Creator<SavedState> CREATOR
498 = new Parcelable.Creator<SavedState>() {
499 public SavedState createFromParcel(Parcel in) {
500 return new SavedState(in);
501 }
502
503 public SavedState[] newArray(int size) {
504 return new SavedState[size];
505 }
506 };
507 }
508
509 @Override
510 public Parcelable onSaveInstanceState() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 Parcelable superState = super.onSaveInstanceState();
512
513 SavedState ss = new SavedState(superState);
514
515 ss.checked = isChecked();
516 return ss;
517 }
518
519 @Override
520 public void onRestoreInstanceState(Parcelable state) {
521 SavedState ss = (SavedState) state;
522
523 super.onRestoreInstanceState(ss.getSuperState());
524 setChecked(ss.checked);
525 requestLayout();
526 }
527}