Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2010 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 | |
| 17 | package com.android.launcher2; |
| 18 | |
Winson Chung | 59e1f9a | 2010-12-21 11:31:54 -0800 | [diff] [blame] | 19 | import android.animation.ObjectAnimator; |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 20 | import android.appwidget.AppWidgetProviderInfo; |
| 21 | import android.content.Context; |
| 22 | import android.content.pm.PackageManager; |
| 23 | import android.content.pm.ResolveInfo; |
Winson Chung | 59e1f9a | 2010-12-21 11:31:54 -0800 | [diff] [blame] | 24 | import android.content.res.Resources; |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 25 | import android.content.res.TypedArray; |
| 26 | import android.graphics.Bitmap; |
| 27 | import android.graphics.Canvas; |
| 28 | import android.graphics.Color; |
| 29 | import android.graphics.Paint; |
Winson Chung | 1908d07 | 2011-02-24 18:09:44 -0800 | [diff] [blame] | 30 | import android.graphics.PorterDuff; |
Winson Chung | c3f9f4f | 2010-12-14 17:25:59 -0800 | [diff] [blame] | 31 | import android.graphics.PorterDuff.Mode; |
Winson Chung | 1908d07 | 2011-02-24 18:09:44 -0800 | [diff] [blame] | 32 | import android.graphics.PorterDuffXfermode; |
| 33 | import android.graphics.Rect; |
| 34 | import android.graphics.RectF; |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 35 | import android.os.Handler; |
| 36 | import android.os.HandlerThread; |
| 37 | import android.os.Message; |
| 38 | import android.util.AttributeSet; |
Winson Chung | 97d85d2 | 2011-04-13 11:27:36 -0700 | [diff] [blame] | 39 | import android.view.KeyEvent; |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 40 | import android.view.MotionEvent; |
Winson Chung | 3e6882c | 2011-01-17 16:37:14 -0800 | [diff] [blame] | 41 | import android.view.View; |
Winson Chung | 59e1f9a | 2010-12-21 11:31:54 -0800 | [diff] [blame] | 42 | import android.widget.Checkable; |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 43 | import android.widget.ImageView; |
| 44 | import android.widget.LinearLayout; |
| 45 | import android.widget.TextView; |
| 46 | |
| 47 | import com.android.launcher.R; |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 48 | |
| 49 | /** |
| 50 | * The linear layout used strictly for the widget/wallpaper tab of the customization tray |
| 51 | */ |
Winson Chung | 59e1f9a | 2010-12-21 11:31:54 -0800 | [diff] [blame] | 52 | public class PagedViewWidget extends LinearLayout implements Checkable { |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 53 | static final String TAG = "PagedViewWidgetLayout"; |
| 54 | |
| 55 | private final Paint mPaint = new Paint(); |
| 56 | private static HolographicOutlineHelper sHolographicOutlineHelper; |
| 57 | private Bitmap mHolographicOutline; |
| 58 | private final Canvas mHolographicOutlineCanvas = new Canvas(); |
| 59 | private FastBitmapDrawable mPreview; |
Winson Chung | 1908d07 | 2011-02-24 18:09:44 -0800 | [diff] [blame] | 60 | private ImageView mPreviewImageView; |
| 61 | private final RectF mTmpScaleRect = new RectF(); |
| 62 | private final Rect mEraseStrokeRect = new Rect(); |
| 63 | private final Paint mEraseStrokeRectPaint = new Paint(); |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 64 | |
Winson Chung | 0499834 | 2011-01-05 13:54:43 -0800 | [diff] [blame] | 65 | private PagedViewIconCache.Key mIconCacheKey; |
| 66 | private PagedViewIconCache mIconCache; |
| 67 | |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 68 | private int mAlpha = 255; |
| 69 | private int mHolographicAlpha; |
| 70 | |
| 71 | // Highlight colors |
| 72 | private int mHoloBlurColor; |
| 73 | private int mHoloOutlineColor; |
| 74 | |
Winson Chung | 59e1f9a | 2010-12-21 11:31:54 -0800 | [diff] [blame] | 75 | private boolean mIsChecked; |
| 76 | private ObjectAnimator mCheckedAlphaAnimator; |
| 77 | private float mCheckedAlpha = 1.0f; |
| 78 | private int mCheckedFadeInDuration; |
| 79 | private int mCheckedFadeOutDuration; |
| 80 | |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 81 | private static final HandlerThread sWorkerThread = new HandlerThread("pagedviewwidget-helper"); |
| 82 | static { |
| 83 | sWorkerThread.start(); |
| 84 | } |
| 85 | |
| 86 | private static final int MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE = 1; |
| 87 | |
| 88 | private static final Handler sWorker = new Handler(sWorkerThread.getLooper()) { |
| 89 | private DeferredHandler mHandler = new DeferredHandler(); |
| 90 | public void handleMessage(Message msg) { |
| 91 | final PagedViewWidget widget = (PagedViewWidget) msg.obj; |
| 92 | final int prevAlpha = widget.mPreview.getAlpha(); |
Winson Chung | 1908d07 | 2011-02-24 18:09:44 -0800 | [diff] [blame] | 93 | final int width = Math.max(widget.mPreview.getIntrinsicWidth(), |
| 94 | widget.getMeasuredWidth()); |
| 95 | final int height = Math.max(widget.mPreview.getIntrinsicHeight(), |
| 96 | widget.getMeasuredHeight()); |
| 97 | final Bitmap outline = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 98 | |
| 99 | widget.mHolographicOutlineCanvas.setBitmap(outline); |
| 100 | widget.mHolographicOutlineCanvas.save(); |
| 101 | widget.mHolographicOutlineCanvas.translate(widget.mPaddingLeft, widget.mPaddingTop); |
| 102 | widget.mPreview.setAlpha(255); |
| 103 | widget.mPreview.draw(widget.mHolographicOutlineCanvas); |
| 104 | widget.mPreview.setAlpha(prevAlpha); |
Winson Chung | c3f9f4f | 2010-12-14 17:25:59 -0800 | [diff] [blame] | 105 | // Temporary workaround to make the default widget outlines visible |
| 106 | widget.mHolographicOutlineCanvas.drawColor(Color.argb(156, 0, 0, 0), Mode.SRC_OVER); |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 107 | widget.mHolographicOutlineCanvas.restore(); |
| 108 | |
Winson Chung | 1908d07 | 2011-02-24 18:09:44 -0800 | [diff] [blame] | 109 | // To account for the fact that some previews run up straight to the edge (we subtract |
| 110 | // the edge from the holographic preview (before we apply the holograph) |
| 111 | widget.mEraseStrokeRect.set(0, 0, width, height); |
| 112 | widget.mHolographicOutlineCanvas.drawRect(widget.mEraseStrokeRect, |
| 113 | widget.mEraseStrokeRectPaint); |
| 114 | |
Adam Cohen | 5bb50bd | 2010-12-03 11:39:55 -0800 | [diff] [blame] | 115 | sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(outline, |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 116 | widget.mHolographicOutlineCanvas, widget.mHoloBlurColor, |
| 117 | widget.mHoloOutlineColor); |
| 118 | |
| 119 | mHandler.post(new Runnable() { |
| 120 | public void run() { |
| 121 | widget.mHolographicOutline = outline; |
Winson Chung | 0499834 | 2011-01-05 13:54:43 -0800 | [diff] [blame] | 122 | widget.mIconCache.addOutline(widget.mIconCacheKey, outline); |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 123 | widget.invalidate(); |
| 124 | } |
| 125 | }); |
| 126 | } |
| 127 | }; |
| 128 | |
| 129 | public PagedViewWidget(Context context) { |
| 130 | this(context, null); |
| 131 | } |
| 132 | |
| 133 | public PagedViewWidget(Context context, AttributeSet attrs) { |
| 134 | this(context, attrs, 0); |
| 135 | } |
| 136 | |
| 137 | public PagedViewWidget(Context context, AttributeSet attrs, int defStyle) { |
| 138 | super(context, attrs, defStyle); |
| 139 | |
| 140 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedViewWidget, |
| 141 | defStyle, 0); |
| 142 | mHoloBlurColor = a.getColor(R.styleable.PagedViewWidget_blurColor, 0); |
| 143 | mHoloOutlineColor = a.getColor(R.styleable.PagedViewWidget_outlineColor, 0); |
Winson Chung | 1908d07 | 2011-02-24 18:09:44 -0800 | [diff] [blame] | 144 | mEraseStrokeRectPaint.setStyle(Paint.Style.STROKE); |
| 145 | mEraseStrokeRectPaint.setStrokeWidth(HolographicOutlineHelper.MIN_OUTER_BLUR_RADIUS); |
| 146 | mEraseStrokeRectPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); |
| 147 | mEraseStrokeRectPaint.setFilterBitmap(true); |
| 148 | mEraseStrokeRectPaint.setAntiAlias(true); |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 149 | a.recycle(); |
| 150 | |
| 151 | if (sHolographicOutlineHelper == null) { |
| 152 | sHolographicOutlineHelper = new HolographicOutlineHelper(); |
| 153 | } |
| 154 | |
Winson Chung | 59e1f9a | 2010-12-21 11:31:54 -0800 | [diff] [blame] | 155 | // Set up fade in/out constants |
| 156 | final Resources r = context.getResources(); |
Winson Chung | 785d2eb | 2011-04-14 16:08:02 -0700 | [diff] [blame^] | 157 | final int alpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha); |
Winson Chung | 59e1f9a | 2010-12-21 11:31:54 -0800 | [diff] [blame] | 158 | if (alpha > 0) { |
Winson Chung | 785d2eb | 2011-04-14 16:08:02 -0700 | [diff] [blame^] | 159 | mCheckedAlpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha) / 256.0f; |
| 160 | mCheckedFadeInDuration = |
| 161 | r.getInteger(R.integer.config_dragAppsCustomizeIconFadeInDuration); |
| 162 | mCheckedFadeOutDuration = |
| 163 | r.getInteger(R.integer.config_dragAppsCustomizeIconFadeOutDuration); |
Winson Chung | 59e1f9a | 2010-12-21 11:31:54 -0800 | [diff] [blame] | 164 | } |
| 165 | |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 166 | setWillNotDraw(false); |
| 167 | setClipToPadding(false); |
| 168 | } |
| 169 | |
| 170 | private void queueHolographicOutlineCreation() { |
| 171 | // Generate the outline in the background |
Winson Chung | 0499834 | 2011-01-05 13:54:43 -0800 | [diff] [blame] | 172 | if (mHolographicOutline == null && mPreview != null) { |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 173 | Message m = sWorker.obtainMessage(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE); |
| 174 | m.obj = this; |
| 175 | sWorker.sendMessage(m); |
| 176 | } |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 177 | } |
| 178 | |
| 179 | public void applyFromAppWidgetProviderInfo(AppWidgetProviderInfo info, |
Winson Chung | 0499834 | 2011-01-05 13:54:43 -0800 | [diff] [blame] | 180 | FastBitmapDrawable preview, int maxWidth, int[] cellSpan, |
| 181 | PagedViewIconCache cache, boolean createHolographicOutline) { |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 182 | final ImageView image = (ImageView) findViewById(R.id.widget_preview); |
| 183 | image.setMaxWidth(maxWidth); |
| 184 | image.setImageDrawable(preview); |
Winson Chung | 1908d07 | 2011-02-24 18:09:44 -0800 | [diff] [blame] | 185 | mPreviewImageView = image; |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 186 | final TextView name = (TextView) findViewById(R.id.widget_name); |
| 187 | name.setText(info.label); |
Winson Chung | 3e6882c | 2011-01-17 16:37:14 -0800 | [diff] [blame] | 188 | name.setLayerType(View.LAYER_TYPE_SOFTWARE, null); |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 189 | final TextView dims = (TextView) findViewById(R.id.widget_dims); |
| 190 | dims.setText(mContext.getString(R.string.widget_dims_format, cellSpan[0], cellSpan[1])); |
Winson Chung | 3e6882c | 2011-01-17 16:37:14 -0800 | [diff] [blame] | 191 | dims.setLayerType(View.LAYER_TYPE_SOFTWARE, null); |
Winson Chung | 0499834 | 2011-01-05 13:54:43 -0800 | [diff] [blame] | 192 | |
| 193 | if (createHolographicOutline) { |
| 194 | mIconCache = cache; |
| 195 | mIconCacheKey = new PagedViewIconCache.Key(info); |
| 196 | mHolographicOutline = mIconCache.getOutline(mIconCacheKey); |
| 197 | mPreview = preview; |
| 198 | } |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 199 | } |
| 200 | |
| 201 | public void applyFromWallpaperInfo(ResolveInfo info, PackageManager packageManager, |
Winson Chung | 0499834 | 2011-01-05 13:54:43 -0800 | [diff] [blame] | 202 | FastBitmapDrawable preview, int maxWidth, PagedViewIconCache cache, |
| 203 | boolean createHolographicOutline) { |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 204 | ImageView image = (ImageView) findViewById(R.id.wallpaper_preview); |
| 205 | image.setMaxWidth(maxWidth); |
| 206 | image.setImageDrawable(preview); |
Winson Chung | 1908d07 | 2011-02-24 18:09:44 -0800 | [diff] [blame] | 207 | mPreviewImageView = image; |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 208 | TextView name = (TextView) findViewById(R.id.wallpaper_name); |
| 209 | name.setText(info.loadLabel(packageManager)); |
Winson Chung | 3e6882c | 2011-01-17 16:37:14 -0800 | [diff] [blame] | 210 | name.setLayerType(View.LAYER_TYPE_SOFTWARE, null); |
Winson Chung | 0499834 | 2011-01-05 13:54:43 -0800 | [diff] [blame] | 211 | |
| 212 | if (createHolographicOutline) { |
| 213 | mIconCache = cache; |
| 214 | mIconCacheKey = new PagedViewIconCache.Key(info); |
| 215 | mHolographicOutline = mIconCache.getOutline(mIconCacheKey); |
| 216 | mPreview = preview; |
| 217 | } |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 218 | } |
| 219 | |
| 220 | @Override |
| 221 | public boolean onTouchEvent(MotionEvent event) { |
| 222 | // We eat up the touch events here, since the PagedView (which uses the same swiping |
| 223 | // touch code as Workspace previously) uses onInterceptTouchEvent() to determine when |
| 224 | // the user is scrolling between pages. This means that if the pages themselves don't |
| 225 | // handle touch events, it gets forwarded up to PagedView itself, and it's own |
| 226 | // onTouchEvent() handling will prevent further intercept touch events from being called |
| 227 | // (it's the same view in that case). This is not ideal, but to prevent more changes, |
| 228 | // we just always mark the touch event as handled. |
| 229 | return super.onTouchEvent(event) || true; |
| 230 | } |
| 231 | |
| 232 | @Override |
Winson Chung | 97d85d2 | 2011-04-13 11:27:36 -0700 | [diff] [blame] | 233 | public boolean onKeyDown(int keyCode, KeyEvent event) { |
| 234 | return FocusHelper.handlePagedViewWidgetKeyEvent(this, keyCode, event) |
| 235 | || super.onKeyDown(keyCode, event); |
| 236 | } |
| 237 | |
| 238 | @Override |
| 239 | public boolean onKeyUp(int keyCode, KeyEvent event) { |
| 240 | return FocusHelper.handlePagedViewWidgetKeyEvent(this, keyCode, event) |
| 241 | || super.onKeyUp(keyCode, event); |
| 242 | } |
| 243 | |
| 244 | @Override |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 245 | protected void onDraw(Canvas canvas) { |
| 246 | if (mAlpha > 0) { |
| 247 | super.onDraw(canvas); |
| 248 | } |
| 249 | |
| 250 | // draw any blended overlays |
| 251 | if (mHolographicOutline != null && mHolographicAlpha > 0) { |
Winson Chung | 1908d07 | 2011-02-24 18:09:44 -0800 | [diff] [blame] | 252 | // Calculate how much to scale the holographic preview |
| 253 | mTmpScaleRect.set(0,0,1,1); |
| 254 | mPreviewImageView.getImageMatrix().mapRect(mTmpScaleRect); |
| 255 | |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 256 | mPaint.setAlpha(mHolographicAlpha); |
Winson Chung | 1908d07 | 2011-02-24 18:09:44 -0800 | [diff] [blame] | 257 | canvas.save(); |
| 258 | canvas.scale(mTmpScaleRect.right, mTmpScaleRect.bottom); |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 259 | canvas.drawBitmap(mHolographicOutline, 0, 0, mPaint); |
Winson Chung | 1908d07 | 2011-02-24 18:09:44 -0800 | [diff] [blame] | 260 | canvas.restore(); |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 261 | } |
| 262 | } |
| 263 | |
| 264 | @Override |
| 265 | protected boolean onSetAlpha(int alpha) { |
| 266 | return true; |
| 267 | } |
| 268 | |
| 269 | @Override |
| 270 | public void setAlpha(float alpha) { |
| 271 | final float viewAlpha = sHolographicOutlineHelper.viewAlphaInterpolator(alpha); |
| 272 | final float holographicAlpha = sHolographicOutlineHelper.highlightAlphaInterpolator(alpha); |
| 273 | int newViewAlpha = (int) (viewAlpha * 255); |
| 274 | int newHolographicAlpha = (int) (holographicAlpha * 255); |
| 275 | if ((mAlpha != newViewAlpha) || (mHolographicAlpha != newHolographicAlpha)) { |
| 276 | mAlpha = newViewAlpha; |
| 277 | mHolographicAlpha = newHolographicAlpha; |
| 278 | setChildrenAlpha(viewAlpha); |
| 279 | super.setAlpha(viewAlpha); |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | private void setChildrenAlpha(float alpha) { |
| 284 | final int childCount = getChildCount(); |
| 285 | for (int i = 0; i < childCount; i++) { |
| 286 | getChildAt(i).setAlpha(alpha); |
| 287 | } |
| 288 | } |
| 289 | |
| 290 | @Override |
| 291 | protected void onSizeChanged(int w, int h, int oldw, int oldh) { |
| 292 | if (w > 0 && h > 0) { |
| 293 | queueHolographicOutlineCreation(); |
| 294 | } |
| 295 | |
| 296 | super.onSizeChanged(w, h, oldw, oldh); |
| 297 | } |
| 298 | |
| 299 | @Override |
| 300 | public void onDetachedFromWindow() { |
| 301 | super.onDetachedFromWindow(); |
| 302 | sWorker.removeMessages(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE, this); |
| 303 | } |
Winson Chung | 59e1f9a | 2010-12-21 11:31:54 -0800 | [diff] [blame] | 304 | |
Patrick Dubroy | 5f44542 | 2011-02-18 14:35:21 -0800 | [diff] [blame] | 305 | void setChecked(boolean checked, boolean animate) { |
Winson Chung | 59e1f9a | 2010-12-21 11:31:54 -0800 | [diff] [blame] | 306 | if (mIsChecked != checked) { |
| 307 | mIsChecked = checked; |
| 308 | |
| 309 | float alpha; |
| 310 | int duration; |
| 311 | if (mIsChecked) { |
| 312 | alpha = mCheckedAlpha; |
| 313 | duration = mCheckedFadeInDuration; |
| 314 | } else { |
| 315 | alpha = 1.0f; |
| 316 | duration = mCheckedFadeOutDuration; |
| 317 | } |
| 318 | |
| 319 | // Initialize the animator |
| 320 | if (mCheckedAlphaAnimator != null) { |
| 321 | mCheckedAlphaAnimator.cancel(); |
| 322 | } |
Patrick Dubroy | 5f44542 | 2011-02-18 14:35:21 -0800 | [diff] [blame] | 323 | if (animate) { |
| 324 | mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha); |
| 325 | mCheckedAlphaAnimator.setDuration(duration); |
| 326 | mCheckedAlphaAnimator.start(); |
| 327 | } else { |
| 328 | setAlpha(alpha); |
| 329 | } |
Winson Chung | 59e1f9a | 2010-12-21 11:31:54 -0800 | [diff] [blame] | 330 | |
| 331 | invalidate(); |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | @Override |
Patrick Dubroy | 5f44542 | 2011-02-18 14:35:21 -0800 | [diff] [blame] | 336 | public void setChecked(boolean checked) { |
| 337 | setChecked(checked, true); |
| 338 | } |
| 339 | |
| 340 | @Override |
Winson Chung | 59e1f9a | 2010-12-21 11:31:54 -0800 | [diff] [blame] | 341 | public boolean isChecked() { |
| 342 | return mIsChecked; |
| 343 | } |
| 344 | |
| 345 | @Override |
| 346 | public void toggle() { |
| 347 | setChecked(!mIsChecked); |
| 348 | } |
Winson Chung | 29d6fea | 2010-12-01 15:47:31 -0800 | [diff] [blame] | 349 | } |