diff options
author | Winson Chung <winsonc@google.com> | 2010-08-19 14:51:28 -0700 |
---|---|---|
committer | Winson Chung <winsonc@google.com> | 2010-08-19 16:00:41 -0700 |
commit | b3347bb9f4ccf41fb7043bca66c3a565bde1083b (patch) | |
tree | 939878ae215eb83c2038942613300e0744099b12 /src | |
parent | 5a74c07c1c1a110e5ef73a596b09f53dd1d58224 (diff) | |
download | android_packages_apps_Trebuchet-b3347bb9f4ccf41fb7043bca66c3a565bde1083b.tar.gz android_packages_apps_Trebuchet-b3347bb9f4ccf41fb7043bca66c3a565bde1083b.tar.bz2 android_packages_apps_Trebuchet-b3347bb9f4ccf41fb7043bca66c3a565bde1083b.zip |
Adding holographic outline for paged items (sans widgets).
Fixing possible null ptr exception in Launcher.
Change-Id: Ie625a6503299cf122e5c22852846d59e66f77414
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/launcher2/AllAppsPagedView.java | 26 | ||||
-rw-r--r-- | src/com/android/launcher2/AllAppsTabbed.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher2/CustomizePagedView.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher2/FastBitmapDrawable.java | 5 | ||||
-rw-r--r-- | src/com/android/launcher2/Launcher.java | 5 | ||||
-rw-r--r-- | src/com/android/launcher2/PagedView.java | 76 | ||||
-rw-r--r-- | src/com/android/launcher2/PagedViewCellLayout.java | 127 | ||||
-rw-r--r-- | src/com/android/launcher2/PagedViewIcon.java | 234 |
8 files changed, 264 insertions, 213 deletions
diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java index 4e819371a..72eeb2233 100644 --- a/src/com/android/launcher2/AllAppsPagedView.java +++ b/src/com/android/launcher2/AllAppsPagedView.java @@ -44,8 +44,7 @@ import com.android.launcher.R; * with all of the user's applications. */ public class AllAppsPagedView extends PagedView - implements AllAppsView, View.OnClickListener, View.OnLongClickListener, DragSource, - PagedViewCellLayout.DimmedBitmapSetupListener { + implements AllAppsView, View.OnClickListener, View.OnLongClickListener, DragSource { private static final String TAG = "AllAppsPagedView"; private static final boolean DEBUG = false; @@ -303,7 +302,6 @@ public class AllAppsPagedView extends PagedView for (int i = curNumPages; i < numPages; ++i) { PagedViewCellLayout layout = new PagedViewCellLayout(getContext()); layout.setCellCount(mCellCountX, mCellCountY); - layout.setDimmedBitmapSetupListener(this); addView(layout); } @@ -343,7 +341,7 @@ public class AllAppsPagedView extends PagedView ApplicationInfo info = mFilteredApps.get(i); TextView text = (TextView) layout.getChildAt(index); text.setCompoundDrawablesWithIntrinsicBounds(null, - new BitmapDrawable(info.iconBitmap), null, null); + new FastBitmapDrawable(info.iconBitmap), null, null); text.setText(info.title); text.setTag(info); @@ -353,24 +351,4 @@ public class AllAppsPagedView extends PagedView params.cellY = index / mCellCountX; } } - - @Override - public void onPreUpdateDimmedBitmap(PagedViewCellLayout layout) { - // disable all children text for now - final int childCount = layout.getChildCount(); - for (int i = 0; i < childCount; ++i) { - TextView text = (TextView) layout.getChildAt(i); - text.setText(""); - } - } - @Override - public void onPostUpdateDimmedBitmap(PagedViewCellLayout layout) { - // re-enable all children text - final int childCount = layout.getChildCount(); - for (int i = 0; i < childCount; ++i) { - TextView text = (TextView) layout.getChildAt(i); - final ApplicationInfo info = (ApplicationInfo) text.getTag(); - text.setText(info.title); - } - } } diff --git a/src/com/android/launcher2/AllAppsTabbed.java b/src/com/android/launcher2/AllAppsTabbed.java index 114da4ed2..5df580cdf 100644 --- a/src/com/android/launcher2/AllAppsTabbed.java +++ b/src/com/android/launcher2/AllAppsTabbed.java @@ -157,8 +157,6 @@ public class AllAppsTabbed extends TabHost implements AllAppsView { super.setVisibility(visibility); float zoom = (isVisible ? 1.0f : 0.0f); mAllApps.zoom(zoom, false); - if (!isVisible) - mAllApps.cleanup(); } @Override diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java index 7679e398c..4a955b224 100644 --- a/src/com/android/launcher2/CustomizePagedView.java +++ b/src/com/android/launcher2/CustomizePagedView.java @@ -353,7 +353,7 @@ public class CustomizePagedView extends PagedView // if we can't find the icon, then just don't draw it } - drawable = new BitmapDrawable(resources, bitmap); + drawable = new FastBitmapDrawable(bitmap); } drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); return drawable; diff --git a/src/com/android/launcher2/FastBitmapDrawable.java b/src/com/android/launcher2/FastBitmapDrawable.java index 226d6d8d8..1cafa09a7 100644 --- a/src/com/android/launcher2/FastBitmapDrawable.java +++ b/src/com/android/launcher2/FastBitmapDrawable.java @@ -17,6 +17,7 @@ package com.android.launcher2; import android.graphics.drawable.Drawable; +import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -26,6 +27,7 @@ class FastBitmapDrawable extends Drawable { private Bitmap mBitmap; private int mWidth; private int mHeight; + private final Paint mPaint = new Paint(); FastBitmapDrawable(Bitmap b) { mBitmap = b; @@ -39,7 +41,7 @@ class FastBitmapDrawable extends Drawable { @Override public void draw(Canvas canvas) { - canvas.drawBitmap(mBitmap, 0.0f, 0.0f, null); + canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint); } @Override @@ -49,6 +51,7 @@ class FastBitmapDrawable extends Drawable { @Override public void setAlpha(int alpha) { + mPaint.setAlpha(alpha); } @Override diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index ebe9baada..ca6539f46 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -2268,7 +2268,6 @@ public final class Launcher extends Activity if (LauncherApplication.isScreenXLarge() && animated) { if (isCustomizationDrawerVisible()) { cameraPan(mHomeCustomizationDrawer, (View) mAllAppsGrid); - mCustomizePagedView.cleanup(); } else { cameraZoomOut((View) mAllAppsGrid, true); } @@ -2369,7 +2368,6 @@ public final class Launcher extends Activity mWorkspace.unshrink(); } cameraZoomIn(mHomeCustomizationDrawer); - mCustomizePagedView.cleanup(); } } @@ -2723,7 +2721,8 @@ public final class Launcher extends Activity */ public void bindPackagesUpdated() { // update the customization drawer contents - mCustomizePagedView.update(); + if (mCustomizePagedView != null) + mCustomizePagedView.update(); } /** diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java index 289a48d4a..03a4d0c03 100644 --- a/src/com/android/launcher2/PagedView.java +++ b/src/com/android/launcher2/PagedView.java @@ -88,7 +88,6 @@ public abstract class PagedView extends ViewGroup { private ScreenSwitchListener mScreenSwitchListener; private boolean mDimmedPagesDirty; - private final Handler mHandler = new Handler(); public interface ScreenSwitchListener { void onScreenSwitch(View newScreen, int newScreenIndex); @@ -262,18 +261,18 @@ public abstract class PagedView extends ViewGroup { int halfChildWidth = (childWidth / 2); int childCenter = getChildOffset(i) + halfChildWidth; int distanceFromScreenCenter = Math.abs(childCenter - screenCenter); - float dimAlpha = 0.0f; + float alpha = 0.0f; if (distanceFromScreenCenter < halfChildWidth) { - dimAlpha = 0.0f; + alpha = 1.0f; } else if (distanceFromScreenCenter > childWidth) { - dimAlpha = 1.0f; + alpha = 0.0f; } else { - dimAlpha = (float) (distanceFromScreenCenter - halfChildWidth) / halfChildWidth; - dimAlpha = (dimAlpha * dimAlpha); + float dimAlpha = (float) (distanceFromScreenCenter - halfChildWidth) / halfChildWidth; + dimAlpha = Math.max(0.0f, Math.min(1.0f, (dimAlpha * dimAlpha))); + alpha = 1.0f - dimAlpha; } - dimAlpha = Math.max(0.0f, Math.min(1.0f, dimAlpha)); - if (Float.compare(dimAlpha, layout.getDimmedBitmapAlpha()) != 0) - layout.setDimmedBitmapAlpha(dimAlpha); + if (Float.compare(alpha, layout.getAlpha()) != 0) + layout.setAlpha(alpha); } } super.dispatchDraw(canvas); @@ -802,78 +801,21 @@ public abstract class PagedView extends ViewGroup { }; } - private void clearDimmedBitmaps(boolean skipCurrentScreens) { - final int count = getChildCount(); - if (mCurrentScreen < count) { - if (skipCurrentScreens) { - int lowerScreenBound = Math.max(0, mCurrentScreen - 1); - int upperScreenBound = Math.min(mCurrentScreen + 1, count - 1); - for (int i = 0; i < count; ++i) { - if (i < lowerScreenBound || i > upperScreenBound) { - PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(i); - layout.clearDimmedBitmap(); - } - } - } else { - for (int i = 0; i < count; ++i) { - PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(i); - layout.clearDimmedBitmap(); - } - } - } - } - Runnable clearLayoutOtherDimmedBitmapsRunnable = new Runnable() { - @Override - public void run() { - if (mScroller.isFinished()) { - clearDimmedBitmaps(true); - mHandler.removeMessages(0); - } else { - mHandler.postDelayed(clearLayoutOtherDimmedBitmapsRunnable, 50); - } - } - }; - Runnable clearLayoutDimmedBitmapsRunnable = new Runnable() { - @Override - public void run() { - if (mScroller.isFinished()) { - clearDimmedBitmaps(false); - mHandler.removeMessages(0); - } else { - mHandler.postDelayed(clearLayoutOtherDimmedBitmapsRunnable, 50); - } - } - }; - - // called when this paged view is no longer visible - public void cleanup() { - // clear all the layout dimmed bitmaps - mHandler.removeMessages(0); - mHandler.postDelayed(clearLayoutDimmedBitmapsRunnable, 500); - } - public void loadAssociatedPages(int screen) { final int count = getChildCount(); if (screen < count) { int lowerScreenBound = Math.max(0, screen - 1); int upperScreenBound = Math.min(screen + 1, count - 1); - boolean hasDimmedBitmap = false; for (int i = 0; i < count; ++i) { if (lowerScreenBound <= i && i <= upperScreenBound) { syncPageItems(i); } else { - PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(i); + final PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(i); if (layout.getChildCount() > 0) { layout.removeAllViews(); } - hasDimmedBitmap |= layout.getDimmedBitmapAlpha() > 0.0f; } } - - if (hasDimmedBitmap) { - mHandler.removeMessages(0); - mHandler.postDelayed(clearLayoutOtherDimmedBitmapsRunnable, 500); - } } } diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java index 16df2a499..24139966a 100644 --- a/src/com/android/launcher2/PagedViewCellLayout.java +++ b/src/com/android/launcher2/PagedViewCellLayout.java @@ -36,24 +36,9 @@ import android.view.ViewGroup; * to give a preview of its contents. */ public class PagedViewCellLayout extends ViewGroup { - public interface DimmedBitmapSetupListener { - public void onPreUpdateDimmedBitmap(PagedViewCellLayout layout); - public void onPostUpdateDimmedBitmap(PagedViewCellLayout layout); - } - static final String TAG = "PagedViewCellLayout"; - // we make the dimmed bitmap smaller than the screen itself for memory + perf reasons - static final float DIMMED_BITMAP_SCALE = 0.75f; - - // a dimmed version of the layout for rendering when in the periphery - private Bitmap mDimmedBitmap; - private Canvas mDimmedBitmapCanvas; - private float mDimmedBitmapAlpha; - private boolean mDimmedBitmapDirty; - private final Paint mDimmedBitmapPaint = new Paint(); - private final Rect mLayoutRect = new Rect(); - private final Rect mDimmedBitmapRect = new Rect(); + private float mHolographicAlpha; private boolean mCenterContent; @@ -63,8 +48,6 @@ public class PagedViewCellLayout extends ViewGroup { private int mCellHeight; private static int sDefaultCellDimensions = 96; - private DimmedBitmapSetupListener mDimmedBitmapSetupListener; - public PagedViewCellLayout(Context context) { this(context, null); } @@ -76,35 +59,25 @@ public class PagedViewCellLayout extends ViewGroup { public PagedViewCellLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - // enable drawing if we have to display a dimmed version of this layout - setWillNotDraw(false); setAlwaysDrawnWithCacheEnabled(false); // setup default cell parameters mCellWidth = mCellHeight = sDefaultCellDimensions; mCellCountX = LauncherModel.getCellCountX(); mCellCountY = LauncherModel.getCellCountY(); - - mDimmedBitmapPaint.setFilterBitmap(true); + mHolographicAlpha = 0.0f; } - public void setDimmedBitmapSetupListener(DimmedBitmapSetupListener listener) { - mDimmedBitmapSetupListener = listener; + @Override + protected boolean onSetAlpha(int alpha) { + return true; } @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - - if (mDimmedBitmap != null && mDimmedBitmapAlpha > 0.0f) { - if (mDimmedBitmapDirty) { - updateDimmedBitmap(); - mDimmedBitmapDirty = false; - } - mDimmedBitmapPaint.setAlpha((int) (mDimmedBitmapAlpha * 255)); - - canvas.drawBitmap(mDimmedBitmap, mDimmedBitmapRect, mLayoutRect, mDimmedBitmapPaint); - } + public void setAlpha(float alpha) { + super.setAlpha(alpha); + setChildrenAlpha(alpha); + mHolographicAlpha = 1.0f - alpha; } @Override @@ -136,28 +109,15 @@ public class PagedViewCellLayout extends ViewGroup { // We might be in the middle or end of shrinking/fading to a dimmed view // Make sure this view's alpha is set the same as all the rest of the views - child.setAlpha(1.0f - mDimmedBitmapAlpha); + child.setAlpha(1.0f - mHolographicAlpha); addView(child, index, lp); - - // next time we draw the dimmed bitmap we need to update it - mDimmedBitmapDirty = true; - invalidate(); return true; } return false; } @Override - public void removeView(View view) { - super.removeView(view); - - // next time we draw the dimmed bitmap we need to update it - mDimmedBitmapDirty = true; - invalidate(); - } - - @Override public void requestChildFocus(View child, View focused) { super.requestChildFocus(child, focused); if (child != null) { @@ -267,13 +227,6 @@ public class PagedViewCellLayout extends ViewGroup { } @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - mLayoutRect.set(0, 0, w, h); - mDimmedBitmapRect.set(0, 0, (int) (DIMMED_BITMAP_SCALE * w), (int) (DIMMED_BITMAP_SCALE * h)); - } - - @Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event) || true; } @@ -299,65 +252,9 @@ public class PagedViewCellLayout extends ViewGroup { requestLayout(); } - public float getDimmedBitmapAlpha() { - return mDimmedBitmapAlpha; - } - - public void setDimmedBitmapAlpha(float alpha) { - // If we're dimming the screen after it was not dimmed, refresh - // to allow for updated widgets. We don't continually refresh it - // after this point, however, as an optimization - if (mDimmedBitmapAlpha == 0.0f && alpha > 0.0f) { - updateDimmedBitmap(); - } - mDimmedBitmapAlpha = alpha; - setChildrenAlpha(1.0f - mDimmedBitmapAlpha); - } - - public void updateDimmedBitmap() { - if (mDimmedBitmapSetupListener != null) { - mDimmedBitmapSetupListener.onPreUpdateDimmedBitmap(this); - } - - if (mDimmedBitmap == null) { - mDimmedBitmap = Bitmap.createBitmap((int) (getWidth() * DIMMED_BITMAP_SCALE), - (int) (getHeight() * DIMMED_BITMAP_SCALE), Bitmap.Config.ARGB_8888); - mDimmedBitmapCanvas = new Canvas(mDimmedBitmap); - mDimmedBitmapCanvas.scale(DIMMED_BITMAP_SCALE, DIMMED_BITMAP_SCALE); - } - // clear the canvas - mDimmedBitmapCanvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR); - - // draw the screen into the bitmap - // just for drawing to the bitmap, make all the items on the screen opaque - setChildrenAlpha(1.0f); - dispatchDraw(mDimmedBitmapCanvas); - setChildrenAlpha(1.0f - mDimmedBitmapAlpha); - - // make the bitmap 'dimmed' ie colored regions are dark grey, - // the rest is light grey - // We draw grey to the whole bitmap, but filter where we draw based on - // what regions are transparent or not (SRC_OUT), causing the intended effect - - // First, draw light grey everywhere in the background (currently transparent) regions - // This will leave the regions with the widgets as mostly transparent - mDimmedBitmapCanvas.drawColor(Color.argb(80, 0, 0, 0), PorterDuff.Mode.SRC_IN); - - if (mDimmedBitmapSetupListener != null) { - mDimmedBitmapSetupListener.onPostUpdateDimmedBitmap(this); - } - } - - public void clearDimmedBitmap() { - setDimmedBitmapAlpha(0.0f); - if (mDimmedBitmap != null) { - mDimmedBitmap.recycle(); - mDimmedBitmap = null; - } - } - private void setChildrenAlpha(float alpha) { - for (int i = 0; i < getChildCount(); i++) { + final int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { getChildAt(i).setAlpha(alpha); } } diff --git a/src/com/android/launcher2/PagedViewIcon.java b/src/com/android/launcher2/PagedViewIcon.java new file mode 100644 index 000000000..e2c22c322 --- /dev/null +++ b/src/com/android/launcher2/PagedViewIcon.java @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher2; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BlurMaskFilter; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PointF; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; +import android.graphics.Region.Op; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.view.View; +import android.widget.TextView; + +class HolographicOutlineHelper { + private final Paint mHolographicPaint = new Paint(); + private final Paint mBlurPaint = new Paint(); + private final Paint mErasePaint = new Paint(); + private static final Matrix mIdentity = new Matrix(); + private static final float STROKE_WIDTH = 6.0f; + private static final float BLUR_FACTOR = 3.5f; + + HolographicOutlineHelper(float density) { + mHolographicPaint.setColor(0xFF6699ff); + mHolographicPaint.setFilterBitmap(true); + mHolographicPaint.setAntiAlias(true); + mBlurPaint.setMaskFilter(new BlurMaskFilter(BLUR_FACTOR * density, + BlurMaskFilter.Blur.OUTER)); + mBlurPaint.setFilterBitmap(true); + mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); + mErasePaint.setFilterBitmap(true); + mErasePaint.setAntiAlias(true); + } + + private float cubic(float r) { + return (float) (Math.pow(r-1, 3) + 1); + } + + /** + * Returns the interpolated holographic highlight alpha for the effect we want when scrolling + * pages. + */ + public float highlightAlphaInterpolator(float r) { + final float pivot = 0.3f; + if (r < pivot) { + return Math.max(0.5f, 0.65f*cubic(r/pivot)); + } else { + return Math.min(1.0f, 0.65f*cubic(1 - (r-pivot)/(1-pivot))); + } + } + + /** + * Returns the interpolated view alpha for the effect we want when scrolling pages. + */ + public float viewAlphaInterpolator(float r) { + final float pivot = 0.6f; + if (r < pivot) { + return r/pivot; + } else { + return 1.0f; + } + } + + /** + * Applies an outline to whatever is currently drawn in the specified bitmap. + */ + void applyOutline(Bitmap srcDst, Canvas srcDstCanvas, PointF offset) { + Bitmap mask = srcDst.extractAlpha(); + Matrix m = new Matrix(); + final int width = srcDst.getWidth(); + final int height = srcDst.getHeight(); + float xScale = STROKE_WIDTH*2.0f/width; + float yScale = STROKE_WIDTH*2.0f/height; + m.preScale(1+xScale, 1+yScale, (width / 2.0f) + offset.x, + (height / 2.0f) + offset.y); + + srcDstCanvas.drawColor(0, PorterDuff.Mode.CLEAR); + srcDstCanvas.drawBitmap(mask, m, mHolographicPaint); + srcDstCanvas.drawBitmap(mask, mIdentity, mErasePaint); + mask.recycle(); + } + + /** + * Applies an blur to whatever is currently drawn in the specified bitmap. + */ + void applyBlur(Bitmap srcDst, Canvas srcDstCanvas) { + int[] xy = new int[2]; + Bitmap mask = srcDst.extractAlpha(mBlurPaint, xy); + srcDstCanvas.drawBitmap(mask, xy[0], xy[1], mHolographicPaint); + mask.recycle(); + } +} + +/** + * An icon on a PagedView, specifically for items in the launcher's paged view (with compound + * drawables on the top). + */ +public class PagedViewIcon extends TextView { + private static final String TAG = "PagedViewIcon"; + + // holographic outline + private final Paint mPaint = new Paint(); + private static HolographicOutlineHelper sHolographicOutlineHelper; + private Bitmap mHolographicOutline; + private Canvas mHolographicOutlineCanvas; + private boolean mIsHolographicUpdatePass; + private Rect mDrawableClipRect; + + private int mAlpha; + private int mHolographicAlpha; + + public PagedViewIcon(Context context) { + this(context, null); + } + + public PagedViewIcon(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public PagedViewIcon(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + if (sHolographicOutlineHelper == null) { + final Resources resources = context.getResources(); + final DisplayMetrics metrics = resources.getDisplayMetrics(); + final float density = metrics.density; + sHolographicOutlineHelper = new HolographicOutlineHelper(density); + } + mDrawableClipRect = new Rect(); + + setFocusable(true); + setBackgroundDrawable(null); + } + + @Override + public void setAlpha(float alpha) { + final float viewAlpha = sHolographicOutlineHelper.viewAlphaInterpolator(alpha); + mAlpha = (int) (viewAlpha * 255); + final float holographicAlpha = sHolographicOutlineHelper.highlightAlphaInterpolator(alpha); + mHolographicAlpha = (int) (holographicAlpha * 255); + + // WORKAROUND: until TextView handles canvas shadow layer alpha itself + int sRed = Color.red(mShadowColor); + int sGreen = Color.green(mShadowColor); + int sBlue = Color.blue(mShadowColor); + super.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, Color.argb(mAlpha, sRed, sGreen, + sBlue)); + + super.setAlpha(viewAlpha); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + + if (mHolographicOutline == null) { + final PointF offset = new PointF(0, + -(getCompoundPaddingBottom() + getCompoundPaddingTop())/2.0f); + + // update the clipping rect to be used in the holographic pass below + getDrawingRect(mDrawableClipRect); + mDrawableClipRect.bottom = getPaddingTop() + getCompoundPaddingTop(); + + // set a flag to indicate that we are going to draw the view at full alpha with the text + // clipped for the generation of the holographic icon + mIsHolographicUpdatePass = true; + mHolographicOutline = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), + Bitmap.Config.ARGB_8888); + mHolographicOutlineCanvas = new Canvas(mHolographicOutline); + mHolographicOutlineCanvas.concat(getMatrix()); + draw(mHolographicOutlineCanvas); + sHolographicOutlineHelper.applyOutline(mHolographicOutline, mHolographicOutlineCanvas, + offset); + sHolographicOutlineHelper.applyBlur(mHolographicOutline, mHolographicOutlineCanvas); + mIsHolographicUpdatePass = false; + } + } + + // WORKAROUND: until TextView handles canvas shadow layer alpha itself + float mShadowRadius, mShadowDx, mShadowDy; + int mShadowColor; + @Override + public void setShadowLayer(float radius, float dx, float dy, int color) { + mShadowRadius = radius; + mShadowDx = dx; + mShadowDy = dy; + mShadowColor = color; + super.setShadowLayer(radius, dx, dy, color); + } + + @Override + protected void onDraw(Canvas canvas) { + if (mIsHolographicUpdatePass) { + // only clip to the text view (restore its alpha so that we get a proper outline) + canvas.save(); + canvas.clipRect(mDrawableClipRect, Op.REPLACE); + super.onSetAlpha(255); + super.onDraw(canvas); + super.onSetAlpha(mAlpha); + canvas.restore(); + } else { + if (mAlpha > 0) { + super.onDraw(canvas); + } + } + + if (!mIsHolographicUpdatePass && mHolographicOutline != null && mHolographicAlpha > 0) { + mPaint.setAlpha(mHolographicAlpha); + canvas.drawBitmap(mHolographicOutline, 0, 0, mPaint); + } + } +} |