PagedViewWidget.java revision b44b52439d155f570db7d6d0b80fdd3350e35685
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 17package com.android.launcher2; 18 19import android.animation.ObjectAnimator; 20import android.appwidget.AppWidgetProviderInfo; 21import android.content.Context; 22import android.content.pm.PackageManager; 23import android.content.pm.ResolveInfo; 24import android.content.res.Resources; 25import android.content.res.TypedArray; 26import android.graphics.Bitmap; 27import android.graphics.Canvas; 28import android.graphics.Color; 29import android.graphics.Paint; 30import android.graphics.PorterDuff; 31import android.graphics.PorterDuff.Mode; 32import android.graphics.PorterDuffXfermode; 33import android.graphics.Rect; 34import android.graphics.RectF; 35import android.os.Handler; 36import android.os.HandlerThread; 37import android.os.Message; 38import android.util.AttributeSet; 39import android.view.KeyEvent; 40import android.view.MotionEvent; 41import android.view.View; 42import android.widget.Checkable; 43import android.widget.ImageView; 44import android.widget.LinearLayout; 45import android.widget.TextView; 46 47import com.android.launcher.R; 48 49/** 50 * The linear layout used strictly for the widget/wallpaper tab of the customization tray 51 */ 52public class PagedViewWidget extends LinearLayout implements Checkable { 53 static final String TAG = "PagedViewWidgetLayout"; 54 55 private final Paint mPaint = new Paint(); 56 private Bitmap mHolographicOutline; 57 private HolographicOutlineHelper mHolographicOutlineHelper; 58 private ImageView mPreviewImageView; 59 private final RectF mTmpScaleRect = new RectF(); 60 61 private String mDimensionsFormatString; 62 63 private int mAlpha = 255; 64 private int mHolographicAlpha; 65 66 private boolean mIsChecked; 67 private ObjectAnimator mCheckedAlphaAnimator; 68 private float mCheckedAlpha = 1.0f; 69 private int mCheckedFadeInDuration; 70 private int mCheckedFadeOutDuration; 71 72 public PagedViewWidget(Context context) { 73 this(context, null); 74 } 75 76 public PagedViewWidget(Context context, AttributeSet attrs) { 77 this(context, attrs, 0); 78 } 79 80 public PagedViewWidget(Context context, AttributeSet attrs, int defStyle) { 81 super(context, attrs, defStyle); 82 83 // Set up fade in/out constants 84 final Resources r = context.getResources(); 85 final int alpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha); 86 if (alpha > 0) { 87 mCheckedAlpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha) / 256.0f; 88 mCheckedFadeInDuration = 89 r.getInteger(R.integer.config_dragAppsCustomizeIconFadeInDuration); 90 mCheckedFadeOutDuration = 91 r.getInteger(R.integer.config_dragAppsCustomizeIconFadeOutDuration); 92 } 93 mDimensionsFormatString = r.getString(R.string.widget_dims_format); 94 95 setWillNotDraw(false); 96 setClipToPadding(false); 97 } 98 99 public void applyFromAppWidgetProviderInfo(AppWidgetProviderInfo info, 100 FastBitmapDrawable preview, int maxWidth, int[] cellSpan, 101 HolographicOutlineHelper holoOutlineHelper) { 102 mHolographicOutlineHelper = holoOutlineHelper; 103 final ImageView image = (ImageView) findViewById(R.id.widget_preview); 104 if (maxWidth > -1) { 105 image.setMaxWidth(maxWidth); 106 } 107 image.setImageDrawable(preview); 108 mPreviewImageView = image; 109 final TextView name = (TextView) findViewById(R.id.widget_name); 110 name.setText(info.label); 111 name.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 112 final TextView dims = (TextView) findViewById(R.id.widget_dims); 113 dims.setText(String.format(mDimensionsFormatString, cellSpan[0], cellSpan[1])); 114 dims.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 115 116 // Hide the divider in the Phone UI. 117 if (!LauncherApplication.isScreenLarge()) { 118 findViewById(R.id.divider).setVisibility(View.GONE); 119 } 120 } 121 122 public void applyFromResolveInfo(PackageManager pm, ResolveInfo info, 123 FastBitmapDrawable preview, HolographicOutlineHelper holoOutlineHelper) { 124 mHolographicOutlineHelper = holoOutlineHelper; 125 final ImageView image = (ImageView) findViewById(R.id.widget_preview); 126 image.setImageDrawable(preview); 127 mPreviewImageView = image; 128 final TextView name = (TextView) findViewById(R.id.widget_name); 129 name.setText(info.loadLabel(pm)); 130 name.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 131 final TextView dims = (TextView) findViewById(R.id.widget_dims); 132 if (dims != null) { 133 dims.setText(String.format(mDimensionsFormatString, 1, 1)); 134 dims.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 135 } 136 137 // Hide the divider in the Phone UI. 138 if (!LauncherApplication.isScreenLarge()) { 139 findViewById(R.id.divider).setVisibility(View.GONE); 140 } 141 } 142 143 public void applyFromWallpaperInfo(ResolveInfo info, PackageManager packageManager, 144 FastBitmapDrawable preview, int maxWidth, HolographicOutlineHelper holoOutlineHelper) { 145 mHolographicOutlineHelper = holoOutlineHelper; 146 ImageView image = (ImageView) findViewById(R.id.wallpaper_preview); 147 image.setMaxWidth(maxWidth); 148 image.setImageDrawable(preview); 149 mPreviewImageView = image; 150 TextView name = (TextView) findViewById(R.id.wallpaper_name); 151 name.setText(info.loadLabel(packageManager)); 152 name.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 153 154 // Hide the divider in the Phone UI. 155 if (!LauncherApplication.isScreenLarge()) { 156 findViewById(R.id.divider).setVisibility(View.GONE); 157 } 158 } 159 160 public void setHolographicOutline(Bitmap holoOutline) { 161 mHolographicOutline = holoOutline; 162 invalidate(); 163 } 164 165 @Override 166 public boolean onTouchEvent(MotionEvent event) { 167 // We eat up the touch events here, since the PagedView (which uses the same swiping 168 // touch code as Workspace previously) uses onInterceptTouchEvent() to determine when 169 // the user is scrolling between pages. This means that if the pages themselves don't 170 // handle touch events, it gets forwarded up to PagedView itself, and it's own 171 // onTouchEvent() handling will prevent further intercept touch events from being called 172 // (it's the same view in that case). This is not ideal, but to prevent more changes, 173 // we just always mark the touch event as handled. 174 return super.onTouchEvent(event) || true; 175 } 176 177 @Override 178 public boolean onKeyDown(int keyCode, KeyEvent event) { 179 return FocusHelper.handlePagedViewGridLayoutWidgetKeyEvent(this, keyCode, event) 180 || super.onKeyDown(keyCode, event); 181 } 182 183 @Override 184 public boolean onKeyUp(int keyCode, KeyEvent event) { 185 return FocusHelper.handlePagedViewGridLayoutWidgetKeyEvent(this, keyCode, event) 186 || super.onKeyUp(keyCode, event); 187 } 188 189 @Override 190 protected void onDraw(Canvas canvas) { 191 if (mAlpha > 0) { 192 super.onDraw(canvas); 193 } 194 195 // draw any blended overlays 196 if (mHolographicOutline != null && mHolographicAlpha > 0) { 197 // Calculate how much to scale the holographic preview 198 mTmpScaleRect.set(0,0,1,1); 199 mPreviewImageView.getImageMatrix().mapRect(mTmpScaleRect); 200 201 mPaint.setAlpha(mHolographicAlpha); 202 canvas.save(); 203 canvas.scale(mTmpScaleRect.right, mTmpScaleRect.bottom); 204 canvas.drawBitmap(mHolographicOutline, 0, 0, mPaint); 205 canvas.restore(); 206 } 207 } 208 209 @Override 210 protected boolean onSetAlpha(int alpha) { 211 return true; 212 } 213 214 private void setChildrenAlpha(float alpha) { 215 final int childCount = getChildCount(); 216 for (int i = 0; i < childCount; i++) { 217 getChildAt(i).setAlpha(alpha); 218 } 219 } 220 @Override 221 public void setAlpha(float alpha) { 222 final float viewAlpha = mHolographicOutlineHelper.viewAlphaInterpolator(alpha); 223 final float holographicAlpha = mHolographicOutlineHelper.highlightAlphaInterpolator(alpha); 224 int newViewAlpha = (int) (viewAlpha * 255); 225 int newHolographicAlpha = (int) (holographicAlpha * 255); 226 if ((mAlpha != newViewAlpha) || (mHolographicAlpha != newHolographicAlpha)) { 227 mAlpha = newViewAlpha; 228 mHolographicAlpha = newHolographicAlpha; 229 setChildrenAlpha(viewAlpha); 230 super.setAlpha(viewAlpha); 231 } 232 } 233 234 void setChecked(boolean checked, boolean animate) { 235 if (mIsChecked != checked) { 236 mIsChecked = checked; 237 238 float alpha; 239 int duration; 240 if (mIsChecked) { 241 alpha = mCheckedAlpha; 242 duration = mCheckedFadeInDuration; 243 } else { 244 alpha = 1.0f; 245 duration = mCheckedFadeOutDuration; 246 } 247 248 // Initialize the animator 249 if (mCheckedAlphaAnimator != null) { 250 mCheckedAlphaAnimator.cancel(); 251 } 252 if (animate) { 253 mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha); 254 mCheckedAlphaAnimator.setDuration(duration); 255 mCheckedAlphaAnimator.start(); 256 } else { 257 setAlpha(alpha); 258 } 259 260 invalidate(); 261 } 262 } 263 264 @Override 265 public void setChecked(boolean checked) { 266 setChecked(checked, true); 267 } 268 269 @Override 270 public boolean isChecked() { 271 return mIsChecked; 272 } 273 274 @Override 275 public void toggle() { 276 setChecked(!mIsChecked); 277 } 278} 279