blob: fede493001f8a2475785837c31ae7ca3327456a8 [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
Dianne Hackborna7bb6fb2015-02-03 18:13:40 -0800327 @Override
328 public CharSequence getAccessibilityClassName() {
329 return CompoundButton.class.getName();
330 }
331
Alan Viverettea54956a2015-01-07 16:05:02 -0800332 /** @hide */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 @Override
Alan Viverettea54956a2015-01-07 16:05:02 -0800334 public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
335 super.onInitializeAccessibilityEventInternal(event);
Svetoslav Ganov736c2752011-04-22 18:30:36 -0700336 event.setChecked(mChecked);
Jean-Baptiste Querucf4550c2009-07-21 11:16:54 -0700337 }
338
Alan Viverettea54956a2015-01-07 16:05:02 -0800339 /** @hide */
Jean-Baptiste Querucf4550c2009-07-21 11:16:54 -0700340 @Override
Alan Viverettea54956a2015-01-07 16:05:02 -0800341 public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
342 super.onInitializeAccessibilityNodeInfoInternal(info);
Svetoslav Ganov0f55cc32011-07-17 10:51:49 -0700343 info.setCheckable(true);
Svetoslav Ganov13774d22011-06-15 15:29:51 -0700344 info.setChecked(mChecked);
345 }
346
347 @Override
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700348 public int getCompoundPaddingLeft() {
349 int padding = super.getCompoundPaddingLeft();
350 if (!isLayoutRtl()) {
351 final Drawable buttonDrawable = mButtonDrawable;
352 if (buttonDrawable != null) {
353 padding += buttonDrawable.getIntrinsicWidth();
354 }
355 }
356 return padding;
357 }
358
359 @Override
360 public int getCompoundPaddingRight() {
361 int padding = super.getCompoundPaddingRight();
362 if (isLayoutRtl()) {
363 final Drawable buttonDrawable = mButtonDrawable;
364 if (buttonDrawable != null) {
365 padding += buttonDrawable.getIntrinsicWidth();
366 }
367 }
368 return padding;
369 }
370
Fabrice Di Megliob878ddb2012-11-27 17:44:33 -0800371 /**
372 * @hide
373 */
374 @Override
375 public int getHorizontalOffsetForDrawables() {
376 final Drawable buttonDrawable = mButtonDrawable;
377 return (buttonDrawable != null) ? buttonDrawable.getIntrinsicWidth() : 0;
378 }
379
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700380 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 protected void onDraw(Canvas canvas) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 final Drawable buttonDrawable = mButtonDrawable;
383 if (buttonDrawable != null) {
384 final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700385 final int drawableHeight = buttonDrawable.getIntrinsicHeight();
386 final int drawableWidth = buttonDrawable.getIntrinsicWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387
Alan Viverette61956602014-04-22 19:07:06 -0700388 final int top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 switch (verticalGravity) {
390 case Gravity.BOTTOM:
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700391 top = getHeight() - drawableHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 break;
393 case Gravity.CENTER_VERTICAL:
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700394 top = (getHeight() - drawableHeight) / 2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 break;
Alan Viverette61956602014-04-22 19:07:06 -0700396 default:
397 top = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 }
Alan Viverette61956602014-04-22 19:07:06 -0700399 final int bottom = top + drawableHeight;
400 final int left = isLayoutRtl() ? getWidth() - drawableWidth : 0;
401 final int right = isLayoutRtl() ? getWidth() : drawableWidth;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402
Fabrice Di Meglio28426792012-06-05 16:41:18 -0700403 buttonDrawable.setBounds(left, top, right, bottom);
Alan Viverette61956602014-04-22 19:07:06 -0700404
405 final Drawable background = getBackground();
Alan Viverettec80ad992014-05-19 15:46:17 -0700406 if (background != null) {
Alan Viverette61956602014-04-22 19:07:06 -0700407 background.setHotspotBounds(left, top, right, bottom);
408 }
409 }
410
411 super.onDraw(canvas);
412
413 if (buttonDrawable != null) {
Alan Viveretteb95c3362014-10-17 17:19:12 -0700414 final int scrollX = mScrollX;
415 final int scrollY = mScrollY;
416 if (scrollX == 0 && scrollY == 0) {
417 buttonDrawable.draw(canvas);
418 } else {
419 canvas.translate(scrollX, scrollY);
420 buttonDrawable.draw(canvas);
421 canvas.translate(-scrollX, -scrollY);
422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 }
424 }
425
426 @Override
427 protected int[] onCreateDrawableState(int extraSpace) {
428 final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
429 if (isChecked()) {
430 mergeDrawableStates(drawableState, CHECKED_STATE_SET);
431 }
432 return drawableState;
433 }
434
435 @Override
436 protected void drawableStateChanged() {
437 super.drawableStateChanged();
438
439 if (mButtonDrawable != null) {
440 int[] myDrawableState = getDrawableState();
441
442 // Set the state of the Drawable
443 mButtonDrawable.setState(myDrawableState);
444
445 invalidate();
446 }
447 }
448
Alan Viverettecebc6ba2014-06-13 15:52:13 -0700449 @Override
Alan Viverette8de14942014-06-18 18:05:15 -0700450 public void drawableHotspotChanged(float x, float y) {
451 super.drawableHotspotChanged(x, y);
Alan Viverettecebc6ba2014-06-13 15:52:13 -0700452
453 if (mButtonDrawable != null) {
454 mButtonDrawable.setHotspot(x, y);
455 }
456 }
457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 @Override
459 protected boolean verifyDrawable(Drawable who) {
460 return super.verifyDrawable(who) || who == mButtonDrawable;
461 }
462
Dianne Hackborne2136772010-11-04 15:08:59 -0700463 @Override
464 public void jumpDrawablesToCurrentState() {
465 super.jumpDrawablesToCurrentState();
466 if (mButtonDrawable != null) mButtonDrawable.jumpToCurrentState();
467 }
468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 static class SavedState extends BaseSavedState {
470 boolean checked;
471
472 /**
473 * Constructor called from {@link CompoundButton#onSaveInstanceState()}
474 */
475 SavedState(Parcelable superState) {
476 super(superState);
477 }
478
479 /**
480 * Constructor called from {@link #CREATOR}
481 */
482 private SavedState(Parcel in) {
483 super(in);
484 checked = (Boolean)in.readValue(null);
485 }
486
487 @Override
488 public void writeToParcel(Parcel out, int flags) {
489 super.writeToParcel(out, flags);
490 out.writeValue(checked);
491 }
492
493 @Override
494 public String toString() {
495 return "CompoundButton.SavedState{"
496 + Integer.toHexString(System.identityHashCode(this))
497 + " checked=" + checked + "}";
498 }
499
500 public static final Parcelable.Creator<SavedState> CREATOR
501 = new Parcelable.Creator<SavedState>() {
502 public SavedState createFromParcel(Parcel in) {
503 return new SavedState(in);
504 }
505
506 public SavedState[] newArray(int size) {
507 return new SavedState[size];
508 }
509 };
510 }
511
512 @Override
513 public Parcelable onSaveInstanceState() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 Parcelable superState = super.onSaveInstanceState();
515
516 SavedState ss = new SavedState(superState);
517
518 ss.checked = isChecked();
519 return ss;
520 }
521
522 @Override
523 public void onRestoreInstanceState(Parcelable state) {
524 SavedState ss = (SavedState) state;
525
526 super.onRestoreInstanceState(ss.getSuperState());
527 setChecked(ss.checked);
528 requestLayout();
529 }
530}