diff --git a/src/com/android/launcher2/BubbleTextView.java b/src/com/android/launcher2/BubbleTextView.java index f4a3d4499a..6039307921 100644 --- a/src/com/android/launcher2/BubbleTextView.java +++ b/src/com/android/launcher2/BubbleTextView.java @@ -19,6 +19,7 @@ package com.android.launcher2; import android.widget.TextView; import android.content.Context; import android.util.AttributeSet; +import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; @@ -32,7 +33,7 @@ import com.android.launcher.R; * because we want to make the bubble taller than the text and TextView's clip is * too aggressive. */ -public class BubbleTextView extends TextView { +public class BubbleTextView extends CacheableTextView { static final float CORNER_RADIUS = 8.0f; static final float PADDING_H = 5.0f; static final float PADDING_V = 1.0f; @@ -77,6 +78,18 @@ public class BubbleTextView extends TextView { mPaddingV = PADDING_V * scale; } + public void applyFromShortcutInfo(ShortcutInfo info, IconCache iconCache) { + Bitmap b = info.getIcon(iconCache); + + setCompoundDrawablesWithIntrinsicBounds(null, + new FastBitmapDrawable(b), + null, null); + setText(info.title); + buildAndEnableCache(); + setTag(info); + + } + @Override protected boolean setFrame(int left, int top, int right, int bottom) { if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) { @@ -129,7 +142,9 @@ public class BubbleTextView extends TextView { top + layout.getLineTop(0) - mPaddingV, Math.min(left + layout.getLineRight(0) + mPaddingH, mScrollX + mRight - mLeft), top + layout.getLineBottom(0) + mPaddingV); - canvas.drawRoundRect(rect, mCornerRadius, mCornerRadius, mPaint); + // TEMPORARILY DISABLE DRAWING ROUND RECT -- re-enable this when we tweak CacheableTextView + // to support padding so we can capture the "rounded" edges + //canvas.drawRoundRect(rect, mCornerRadius, mCornerRadius, mPaint); super.draw(canvas); } diff --git a/src/com/android/launcher2/CacheableTextView.java b/src/com/android/launcher2/CacheableTextView.java new file mode 100644 index 0000000000..26eafa9333 --- /dev/null +++ b/src/com/android/launcher2/CacheableTextView.java @@ -0,0 +1,122 @@ +/* + * 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.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Bitmap.Config; +import android.text.Layout; +import android.util.AttributeSet; +import android.widget.TextView; + +/* + * This class is a bit of a hack, designed to speed up long text labels in Launcher. It caches the + * text in a TextView to a bitmap and then just draws that Bitmap instead afterward, speeding up + * rendering. Marquee scrolling is not currently supported. + * + */ +public class CacheableTextView extends TextView { + private Bitmap mCache; + private final Paint mCachePaint = new Paint(); + + private int mPrevAlpha = -1; + private boolean mIsBuildingCache; + boolean mWaitingToGenerateCache; + float mTextCacheLeft; + float mTextCacheTop; + float mTextCacheScrollX; + float mRectLeft, mRectTop; + private float mPaddingH = 0; + private float mPaddingV = 0; + + public CacheableTextView(Context context) { + super(context); + } + + public CacheableTextView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public CacheableTextView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public void buildAndEnableCache() { + if (getLayout() == null) { + mWaitingToGenerateCache = true; + return; + } + + final Layout layout = getLayout(); + + final int left = getCompoundPaddingLeft(); + final int top = getExtendedPaddingTop(); + mTextCacheLeft = layout.getLineLeft(0); + mTextCacheTop = top + layout.getLineTop(0) - mPaddingV; + + mRectLeft = mScrollX + getLeft(); + mRectTop = 0; + mTextCacheScrollX = mScrollX; + + final float textCacheRight = + Math.min(left + layout.getLineRight(0) + mPaddingH, mScrollX + mRight - mLeft); + final float textCacheBottom = top + layout.getLineBottom(0) + mPaddingV; + + mCache = Bitmap.createBitmap((int) (textCacheRight - mTextCacheLeft), + (int) (textCacheBottom - mTextCacheTop), Config.ARGB_8888); + Canvas c = new Canvas(mCache); + c.translate(-mTextCacheLeft, -mTextCacheTop); + + mIsBuildingCache = true; + float alpha = getAlpha(); + setAlpha(1.0f); + draw(c); + setAlpha(alpha); + mIsBuildingCache = false; + mCachePaint.setFilterBitmap(true); + + // A hack-- we set the text to be one space (we don't make it empty just to avoid any + // potential issues with text measurement, like line height, etc.) so that the text view + // doesn't draw it anymore, since it's been cached. We have to manually rebuild + // the cache whenever the text is changed (which is never in Launcher) + setText(" "); + } + + public void draw(Canvas canvas) { + if (mWaitingToGenerateCache && !mIsBuildingCache) { + buildAndEnableCache(); + mWaitingToGenerateCache = false; + } + if (mCache != null) { + canvas.drawBitmap(mCache, mTextCacheLeft - mTextCacheScrollX + mScrollX, + mTextCacheTop, mCachePaint); + } + super.draw(canvas); + } + + @Override + protected boolean onSetAlpha(int alpha) { + if (mPrevAlpha != alpha) { + mPrevAlpha = alpha; + mCachePaint.setAlpha(alpha); + super.onSetAlpha(alpha); + } + return true; + } +} \ No newline at end of file diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index 033ccc3d44..eacaef9080 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -1038,17 +1038,9 @@ public final class Launcher extends Activity * @return A View inflated from layoutResId. */ View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) { - TextView favorite = (TextView) mInflater.inflate(layoutResId, parent, false); - - Bitmap b = info.getIcon(mIconCache); - - favorite.setCompoundDrawablesWithIntrinsicBounds(null, - new FastBitmapDrawable(b), - null, null); - favorite.setText(info.title); - favorite.setTag(info); + BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false); + favorite.applyFromShortcutInfo(info, mIconCache); favorite.setOnClickListener(this); - return favorite; } diff --git a/src/com/android/launcher2/PagedViewIcon.java b/src/com/android/launcher2/PagedViewIcon.java index b9b9b377e3..9e48351688 100644 --- a/src/com/android/launcher2/PagedViewIcon.java +++ b/src/com/android/launcher2/PagedViewIcon.java @@ -39,7 +39,7 @@ import com.android.launcher2.PagedView.PagedViewIconCache; * 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 implements Checkable { +public class PagedViewIcon extends CacheableTextView implements Checkable { private static final String TAG = "PagedViewIcon"; // holographic outline @@ -138,6 +138,7 @@ public class PagedViewIcon extends TextView implements Checkable { mIcon = info.iconBitmap; setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null); setText(info.title); + buildAndEnableCache(); setTag(info); queueHolographicOutlineCreation(); @@ -153,6 +154,7 @@ public class PagedViewIcon extends TextView implements Checkable { modelIconCache.getFullResIcon(info, packageManager), mContext); setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null); setText(info.loadLabel(packageManager)); + buildAndEnableCache(); setTag(info); queueHolographicOutlineCreation();