PagedViewWidget.java revision fd3385fe9e0f034b04f99d5d59a58d74fe040da4
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 117 public void applyFromResolveInfo(PackageManager pm, ResolveInfo info, 118 FastBitmapDrawable preview, HolographicOutlineHelper holoOutlineHelper) { 119 mHolographicOutlineHelper = holoOutlineHelper; 120 final ImageView image = (ImageView) findViewById(R.id.widget_preview); 121 image.setImageDrawable(preview); 122 mPreviewImageView = image; 123 final TextView name = (TextView) findViewById(R.id.widget_name); 124 name.setText(info.loadLabel(pm)); 125 name.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 126 final TextView dims = (TextView) findViewById(R.id.widget_dims); 127 if (dims != null) { 128 dims.setText(String.format(mDimensionsFormatString, 1, 1)); 129 dims.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 130 } 131 } 132 133 public void setHolographicOutline(Bitmap holoOutline) { 134 mHolographicOutline = holoOutline; 135 invalidate(); 136 } 137 138 @Override 139 public boolean onTouchEvent(MotionEvent event) { 140 // We eat up the touch events here, since the PagedView (which uses the same swiping 141 // touch code as Workspace previously) uses onInterceptTouchEvent() to determine when 142 // the user is scrolling between pages. This means that if the pages themselves don't 143 // handle touch events, it gets forwarded up to PagedView itself, and it's own 144 // onTouchEvent() handling will prevent further intercept touch events from being called 145 // (it's the same view in that case). This is not ideal, but to prevent more changes, 146 // we just always mark the touch event as handled. 147 return super.onTouchEvent(event) || true; 148 } 149 150 @Override 151 public boolean onKeyDown(int keyCode, KeyEvent event) { 152 return FocusHelper.handlePagedViewGridLayoutWidgetKeyEvent(this, keyCode, event) 153 || super.onKeyDown(keyCode, event); 154 } 155 156 @Override 157 public boolean onKeyUp(int keyCode, KeyEvent event) { 158 return FocusHelper.handlePagedViewGridLayoutWidgetKeyEvent(this, keyCode, event) 159 || super.onKeyUp(keyCode, event); 160 } 161 162 @Override 163 protected void onDraw(Canvas canvas) { 164 if (mAlpha > 0) { 165 super.onDraw(canvas); 166 } 167 168 // draw any blended overlays 169 if (mHolographicOutline != null && mHolographicAlpha > 0) { 170 // Calculate how much to scale the holographic preview 171 mTmpScaleRect.set(0,0,1,1); 172 mPreviewImageView.getImageMatrix().mapRect(mTmpScaleRect); 173 174 mPaint.setAlpha(mHolographicAlpha); 175 canvas.save(); 176 canvas.scale(mTmpScaleRect.right, mTmpScaleRect.bottom); 177 canvas.drawBitmap(mHolographicOutline, mPreviewImageView.getLeft(), 178 mPreviewImageView.getTop(), mPaint); 179 canvas.restore(); 180 } 181 } 182 183 @Override 184 protected boolean onSetAlpha(int alpha) { 185 return true; 186 } 187 188 private void setChildrenAlpha(float alpha) { 189 final int childCount = getChildCount(); 190 for (int i = 0; i < childCount; i++) { 191 getChildAt(i).setAlpha(alpha); 192 } 193 } 194 @Override 195 public void setAlpha(float alpha) { 196 final float viewAlpha = mHolographicOutlineHelper.viewAlphaInterpolator(alpha); 197 final float holographicAlpha = mHolographicOutlineHelper.highlightAlphaInterpolator(alpha); 198 int newViewAlpha = (int) (viewAlpha * 255); 199 int newHolographicAlpha = (int) (holographicAlpha * 255); 200 if ((mAlpha != newViewAlpha) || (mHolographicAlpha != newHolographicAlpha)) { 201 mAlpha = newViewAlpha; 202 mHolographicAlpha = newHolographicAlpha; 203 setChildrenAlpha(viewAlpha); 204 super.setAlpha(viewAlpha); 205 } 206 } 207 208 void setChecked(boolean checked, boolean animate) { 209 if (mIsChecked != checked) { 210 mIsChecked = checked; 211 212 float alpha; 213 int duration; 214 if (mIsChecked) { 215 alpha = mCheckedAlpha; 216 duration = mCheckedFadeInDuration; 217 } else { 218 alpha = 1.0f; 219 duration = mCheckedFadeOutDuration; 220 } 221 222 // Initialize the animator 223 if (mCheckedAlphaAnimator != null) { 224 mCheckedAlphaAnimator.cancel(); 225 } 226 if (animate) { 227 mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha); 228 mCheckedAlphaAnimator.setDuration(duration); 229 mCheckedAlphaAnimator.start(); 230 } else { 231 setAlpha(alpha); 232 } 233 234 invalidate(); 235 } 236 } 237 238 @Override 239 public void setChecked(boolean checked) { 240 setChecked(checked, true); 241 } 242 243 @Override 244 public boolean isChecked() { 245 return mIsChecked; 246 } 247 248 @Override 249 public void toggle() { 250 setChecked(!mIsChecked); 251 } 252} 253