Loading src/com/android/launcher3/BubbleTextView.java +4 −4 Original line number Diff line number Diff line Loading @@ -167,7 +167,7 @@ public class BubbleTextView extends TextView applyPromiseState(promiseStateChanged); } applyBadgeState(info); applyBadgeState(info, false /* animate */); } public void applyFromApplicationInfo(AppInfo info) { Loading @@ -179,7 +179,7 @@ public class BubbleTextView extends TextView // Verify high res immediately verifyHighRes(); applyBadgeState(info); applyBadgeState(info, false /* animate */); } public void applyFromPackageItemInfo(PackageItemInfo info) { Loading Loading @@ -501,11 +501,11 @@ public class BubbleTextView extends TextView } } public void applyBadgeState(ItemInfo itemInfo) { public void applyBadgeState(ItemInfo itemInfo, boolean animate) { if (mIcon instanceof FastBitmapDrawable) { BadgeInfo badgeInfo = mLauncher.getPopupDataProvider().getBadgeInfoForItem(itemInfo); BadgeRenderer badgeRenderer = mLauncher.getDeviceProfile().mBadgeRenderer; ((FastBitmapDrawable) mIcon).applyIconBadge(badgeInfo, badgeRenderer); ((FastBitmapDrawable) mIcon).applyIconBadge(badgeInfo, badgeRenderer, animate); } } Loading src/com/android/launcher3/FastBitmapDrawable.java +28 −5 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.util.Log; import android.util.Property; import android.util.SparseArray; import android.view.animation.DecelerateInterpolator; Loading Loading @@ -107,6 +107,21 @@ public class FastBitmapDrawable extends Drawable { private BadgeInfo mBadgeInfo; private BadgeRenderer mBadgeRenderer; private IconPalette mIconPalette; private float mBadgeScale; private static final Property<FastBitmapDrawable, Float> BADGE_SCALE_PROPERTY = new Property<FastBitmapDrawable, Float>(Float.TYPE, "badgeScale") { @Override public Float get(FastBitmapDrawable fastBitmapDrawable) { return fastBitmapDrawable.mBadgeScale; } @Override public void set(FastBitmapDrawable fastBitmapDrawable, Float value) { fastBitmapDrawable.mBadgeScale = value; fastBitmapDrawable.invalidateSelf(); } }; // The saturation and brightness are values that are mapped to REDUCED_FILTER_VALUE_SPACE and // as a result, can be used to compose the key for the cached ColorMatrixColorFilters Loading @@ -123,16 +138,24 @@ public class FastBitmapDrawable extends Drawable { setFilterBitmap(true); } public void applyIconBadge(BadgeInfo badgeInfo, BadgeRenderer badgeRenderer) { public void applyIconBadge(final BadgeInfo badgeInfo, BadgeRenderer badgeRenderer, boolean animate) { boolean wasBadged = mBadgeInfo != null; boolean isBadged = badgeInfo != null; float newBadgeScale = isBadged ? 1f : 0; mBadgeInfo = badgeInfo; mBadgeRenderer = badgeRenderer; if (wasBadged || isBadged) { mIconPalette = getIconPalette(); // Animate when a badge is first added or when it is removed. if (animate && (wasBadged ^ isBadged) && isVisible()) { ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, newBadgeScale).start(); } else { mBadgeScale = newBadgeScale; invalidateSelf(); } } } @Override public void draw(Canvas canvas) { Loading @@ -154,7 +177,7 @@ public class FastBitmapDrawable extends Drawable { protected void drawBadgeIfNecessary(Canvas canvas) { if (hasBadge()) { mBadgeRenderer.draw(canvas, mIconPalette, mBadgeInfo, getBounds()); mBadgeRenderer.draw(canvas, mIconPalette, mBadgeInfo, getBounds(), mBadgeScale); } } Loading @@ -167,7 +190,7 @@ public class FastBitmapDrawable extends Drawable { } private boolean hasBadge() { return mBadgeInfo != null && mBadgeInfo.getNotificationCount() != 0; return (mBadgeInfo != null && mBadgeInfo.getNotificationCount() > 0) || mBadgeScale > 0; } @Override Loading src/com/android/launcher3/Workspace.java +1 −1 Original line number Diff line number Diff line Loading @@ -3993,7 +3993,7 @@ public class Workspace extends PagedView if (info instanceof ShortcutInfo && v instanceof BubbleTextView && packageUserKey.updateFromItemInfo(info)) { if (updatedBadges.contains(packageUserKey)) { ((BubbleTextView) v).applyBadgeState(info); ((BubbleTextView) v).applyBadgeState(info, true /* animate */); folderIds.add(info.container); } } Loading src/com/android/launcher3/badge/BadgeRenderer.java +32 −34 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.support.annotation.Nullable; import com.android.launcher3.R; import com.android.launcher3.graphics.IconPalette; Loading @@ -34,62 +35,59 @@ import com.android.launcher3.graphics.IconPalette; */ public class BadgeRenderer { public int size; public int textSize; public IconDrawer largeIconDrawer; public IconDrawer smallIconDrawer; private final Context mContext; private final RectF mBackgroundRect = new RectF(); private final int mSize; private final int mTextHeight; private final IconDrawer mLargeIconDrawer; private final IconDrawer mSmallIconDrawer; private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final int mTextHeight; public BadgeRenderer(Context context) { mContext = context; Resources res = context.getResources(); size = res.getDimensionPixelSize(R.dimen.badge_size); textSize = res.getDimensionPixelSize(R.dimen.badge_text_size); largeIconDrawer = new IconDrawer(res.getDimensionPixelSize(R.dimen.badge_small_padding)); smallIconDrawer = new IconDrawer(res.getDimensionPixelSize(R.dimen.badge_large_padding)); mSize = res.getDimensionPixelSize(R.dimen.badge_size); mLargeIconDrawer = new IconDrawer(res.getDimensionPixelSize(R.dimen.badge_small_padding)); mSmallIconDrawer = new IconDrawer(res.getDimensionPixelSize(R.dimen.badge_large_padding)); mTextPaint.setTextAlign(Paint.Align.CENTER); mTextPaint.setTextSize(textSize); mTextPaint.setTextSize(res.getDimensionPixelSize(R.dimen.badge_text_size)); // Measure the text height. Rect temp = new Rect(); mTextPaint.getTextBounds("0", 0, 1, temp); mTextHeight = temp.height(); Rect tempTextHeight = new Rect(); mTextPaint.getTextBounds("0", 0, 1, tempTextHeight); mTextHeight = tempTextHeight.height(); } /** * Draw a circle in the top right corner of the given bounds, and draw * {@link BadgeInfo#getNotificationCount()} on top of the circle. * @param palette The colors (based on the icon) to use for the badge. * @param badgeInfo Contains data to draw on the badge. * @param badgeInfo Contains data to draw on the badge. Could be null if we are animating out. * @param iconBounds The bounds of the icon being badged. * @param badgeScale The progress of the animation, from 0 to 1. */ public void draw(Canvas canvas, IconPalette palette, BadgeInfo badgeInfo, Rect iconBounds) { public void draw(Canvas canvas, IconPalette palette, @Nullable BadgeInfo badgeInfo, Rect iconBounds, float badgeScale) { mBackgroundPaint.setColor(palette.backgroundColor); mTextPaint.setColor(palette.textColor); mBackgroundRect.set(iconBounds.right - size, iconBounds.top, iconBounds.right, iconBounds.top + size); canvas.drawOval(mBackgroundRect, mBackgroundPaint); IconDrawer iconDrawer = badgeInfo.isIconLarge() ? largeIconDrawer : smallIconDrawer; Shader icon = badgeInfo.getNotificationIconForBadge(mContext, palette.backgroundColor, size, iconDrawer.mPadding); canvas.save(Canvas.MATRIX_SAVE_FLAG); // We draw the badge relative to its center. canvas.translate(iconBounds.right - mSize / 2, iconBounds.top + mSize / 2); canvas.scale(badgeScale, badgeScale); canvas.drawCircle(0, 0, mSize / 2, mBackgroundPaint); IconDrawer iconDrawer = badgeInfo != null && badgeInfo.isIconLarge() ? mLargeIconDrawer : mSmallIconDrawer; Shader icon = badgeInfo == null ? null : badgeInfo.getNotificationIconForBadge( mContext, palette.backgroundColor, mSize, iconDrawer.mPadding); if (icon != null) { // Draw the notification icon with padding. canvas.save(); canvas.translate(mBackgroundRect.left, mBackgroundRect.top); iconDrawer.drawIcon(icon, canvas); canvas.restore(); } else { // Draw the notification count. String notificationCount = String.valueOf(badgeInfo.getNotificationCount()); canvas.drawText(notificationCount, mBackgroundRect.centerX(), mBackgroundRect.centerY() + mTextHeight / 2, mTextPaint); String notificationCount = badgeInfo == null ? "0" : String.valueOf(badgeInfo.getNotificationCount()); canvas.drawText(notificationCount, 0, mTextHeight / 2, mTextPaint); } canvas.restore(); } /** Draws the notification icon with padding of a given size. */ Loading @@ -102,15 +100,15 @@ public class BadgeRenderer { public IconDrawer(int padding) { mPadding = padding; mCircleClipBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ALPHA_8); mCircleClipBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ALPHA_8); Canvas canvas = new Canvas(); canvas.setBitmap(mCircleClipBitmap); canvas.drawCircle(size / 2, size / 2, size / 2 - padding, mPaint); canvas.drawCircle(mSize / 2, mSize / 2, mSize / 2 - padding, mPaint); } public void drawIcon(Shader icon, Canvas canvas) { mPaint.setShader(icon); canvas.drawBitmap(mCircleClipBitmap, 0f, 0f, mPaint); canvas.drawBitmap(mCircleClipBitmap, -mSize / 2, -mSize / 2, mPaint); mPaint.setShader(null); } } Loading src/com/android/launcher3/folder/FolderIcon.java +52 −3 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.graphics.drawable.Drawable; import android.os.Parcelable; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Property; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; Loading Loading @@ -130,6 +131,21 @@ public class FolderIcon extends FrameLayout implements FolderListener { private FolderBadgeInfo mBadgeInfo = new FolderBadgeInfo(); private BadgeRenderer mBadgeRenderer; private float mBadgeScale; private static final Property<FolderIcon, Float> BADGE_SCALE_PROPERTY = new Property<FolderIcon, Float>(Float.TYPE, "badgeScale") { @Override public Float get(FolderIcon folderIcon) { return folderIcon.mBadgeScale; } @Override public void set(FolderIcon folderIcon, Float value) { folderIcon.mBadgeScale = value; folderIcon.invalidate(); } }; public FolderIcon(Context context, AttributeSet attrs) { super(context, attrs); Loading Loading @@ -388,9 +404,26 @@ public class FolderIcon extends FrameLayout implements FolderListener { } public void setBadgeInfo(FolderBadgeInfo badgeInfo) { updateBadgeScale(mBadgeInfo.getNotificationCount(), badgeInfo.getNotificationCount()); mBadgeInfo = badgeInfo; } /** * Sets mBadgeScale to 1 or 0, animating if oldCount or newCount is 0 * (the badge is being added or removed). */ private void updateBadgeScale(int oldCount, int newCount) { boolean wasBadged = oldCount > 0; boolean isBadged = newCount > 0; float newBadgeScale = isBadged ? 1f : 0f; // Animate when a badge is first added or when it is removed. if ((wasBadged ^ isBadged) && isShown()) { ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, newBadgeScale).start(); } else { mBadgeScale = newBadgeScale; invalidate(); } } static class PreviewItemDrawingParams { PreviewItemDrawingParams(float transX, float transY, float scale, float overlayAlpha) { Loading Loading @@ -550,6 +583,14 @@ public class FolderIcon extends FrameLayout implements FolderListener { return basePreviewOffsetY - (getScaledRadius() - getRadius()); } /** * Returns the progress of the scale animation, where 0 means the scale is at 1f * and 1 means the scale is at ACCEPT_SCALE_FACTOR. */ float getScaleProgress() { return (mScale - 1f) / (ACCEPT_SCALE_FACTOR - 1f); } void invalidate() { int radius = getScaledRadius(); mClipPath.reset(); Loading Loading @@ -785,8 +826,10 @@ public class FolderIcon extends FrameLayout implements FolderListener { int offsetY = mBackground.getOffsetY(); int previewSize = (int) (mBackground.previewSize * mBackground.mScale); Rect bounds = new Rect(offsetX, offsetY, offsetX + previewSize, offsetY + previewSize); if (mBadgeInfo != null && mBadgeInfo.getNotificationCount() > 0) { mBadgeRenderer.draw(canvas, IconPalette.FOLDER_ICON_PALETTE, mBadgeInfo, bounds); if ((mBadgeInfo != null && mBadgeInfo.getNotificationCount() > 0) || mBadgeScale > 0) { // If we are animating to the accepting state, animate the badge out. float badgeScale = Math.max(0, mBadgeScale - mBackground.getScaleProgress()); mBadgeRenderer.draw(canvas, IconPalette.FOLDER_ICON_PALETTE, mBadgeInfo, bounds, badgeScale); } } Loading Loading @@ -939,14 +982,20 @@ public class FolderIcon extends FrameLayout implements FolderListener { @Override public void onAdd(ShortcutInfo item) { int oldCount = mBadgeInfo.getNotificationCount(); mBadgeInfo.addBadgeInfo(mLauncher.getPopupDataProvider().getBadgeInfoForItem(item)); int newCount = mBadgeInfo.getNotificationCount(); updateBadgeScale(oldCount, newCount); invalidate(); requestLayout(); } @Override public void onRemove(ShortcutInfo item) { int oldCount = mBadgeInfo.getNotificationCount(); mBadgeInfo.subtractBadgeInfo(mLauncher.getPopupDataProvider().getBadgeInfoForItem(item)); int newCount = mBadgeInfo.getNotificationCount(); updateBadgeScale(oldCount, newCount); invalidate(); requestLayout(); } Loading Loading
src/com/android/launcher3/BubbleTextView.java +4 −4 Original line number Diff line number Diff line Loading @@ -167,7 +167,7 @@ public class BubbleTextView extends TextView applyPromiseState(promiseStateChanged); } applyBadgeState(info); applyBadgeState(info, false /* animate */); } public void applyFromApplicationInfo(AppInfo info) { Loading @@ -179,7 +179,7 @@ public class BubbleTextView extends TextView // Verify high res immediately verifyHighRes(); applyBadgeState(info); applyBadgeState(info, false /* animate */); } public void applyFromPackageItemInfo(PackageItemInfo info) { Loading Loading @@ -501,11 +501,11 @@ public class BubbleTextView extends TextView } } public void applyBadgeState(ItemInfo itemInfo) { public void applyBadgeState(ItemInfo itemInfo, boolean animate) { if (mIcon instanceof FastBitmapDrawable) { BadgeInfo badgeInfo = mLauncher.getPopupDataProvider().getBadgeInfoForItem(itemInfo); BadgeRenderer badgeRenderer = mLauncher.getDeviceProfile().mBadgeRenderer; ((FastBitmapDrawable) mIcon).applyIconBadge(badgeInfo, badgeRenderer); ((FastBitmapDrawable) mIcon).applyIconBadge(badgeInfo, badgeRenderer, animate); } } Loading
src/com/android/launcher3/FastBitmapDrawable.java +28 −5 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.util.Log; import android.util.Property; import android.util.SparseArray; import android.view.animation.DecelerateInterpolator; Loading Loading @@ -107,6 +107,21 @@ public class FastBitmapDrawable extends Drawable { private BadgeInfo mBadgeInfo; private BadgeRenderer mBadgeRenderer; private IconPalette mIconPalette; private float mBadgeScale; private static final Property<FastBitmapDrawable, Float> BADGE_SCALE_PROPERTY = new Property<FastBitmapDrawable, Float>(Float.TYPE, "badgeScale") { @Override public Float get(FastBitmapDrawable fastBitmapDrawable) { return fastBitmapDrawable.mBadgeScale; } @Override public void set(FastBitmapDrawable fastBitmapDrawable, Float value) { fastBitmapDrawable.mBadgeScale = value; fastBitmapDrawable.invalidateSelf(); } }; // The saturation and brightness are values that are mapped to REDUCED_FILTER_VALUE_SPACE and // as a result, can be used to compose the key for the cached ColorMatrixColorFilters Loading @@ -123,16 +138,24 @@ public class FastBitmapDrawable extends Drawable { setFilterBitmap(true); } public void applyIconBadge(BadgeInfo badgeInfo, BadgeRenderer badgeRenderer) { public void applyIconBadge(final BadgeInfo badgeInfo, BadgeRenderer badgeRenderer, boolean animate) { boolean wasBadged = mBadgeInfo != null; boolean isBadged = badgeInfo != null; float newBadgeScale = isBadged ? 1f : 0; mBadgeInfo = badgeInfo; mBadgeRenderer = badgeRenderer; if (wasBadged || isBadged) { mIconPalette = getIconPalette(); // Animate when a badge is first added or when it is removed. if (animate && (wasBadged ^ isBadged) && isVisible()) { ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, newBadgeScale).start(); } else { mBadgeScale = newBadgeScale; invalidateSelf(); } } } @Override public void draw(Canvas canvas) { Loading @@ -154,7 +177,7 @@ public class FastBitmapDrawable extends Drawable { protected void drawBadgeIfNecessary(Canvas canvas) { if (hasBadge()) { mBadgeRenderer.draw(canvas, mIconPalette, mBadgeInfo, getBounds()); mBadgeRenderer.draw(canvas, mIconPalette, mBadgeInfo, getBounds(), mBadgeScale); } } Loading @@ -167,7 +190,7 @@ public class FastBitmapDrawable extends Drawable { } private boolean hasBadge() { return mBadgeInfo != null && mBadgeInfo.getNotificationCount() != 0; return (mBadgeInfo != null && mBadgeInfo.getNotificationCount() > 0) || mBadgeScale > 0; } @Override Loading
src/com/android/launcher3/Workspace.java +1 −1 Original line number Diff line number Diff line Loading @@ -3993,7 +3993,7 @@ public class Workspace extends PagedView if (info instanceof ShortcutInfo && v instanceof BubbleTextView && packageUserKey.updateFromItemInfo(info)) { if (updatedBadges.contains(packageUserKey)) { ((BubbleTextView) v).applyBadgeState(info); ((BubbleTextView) v).applyBadgeState(info, true /* animate */); folderIds.add(info.container); } } Loading
src/com/android/launcher3/badge/BadgeRenderer.java +32 −34 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.support.annotation.Nullable; import com.android.launcher3.R; import com.android.launcher3.graphics.IconPalette; Loading @@ -34,62 +35,59 @@ import com.android.launcher3.graphics.IconPalette; */ public class BadgeRenderer { public int size; public int textSize; public IconDrawer largeIconDrawer; public IconDrawer smallIconDrawer; private final Context mContext; private final RectF mBackgroundRect = new RectF(); private final int mSize; private final int mTextHeight; private final IconDrawer mLargeIconDrawer; private final IconDrawer mSmallIconDrawer; private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final int mTextHeight; public BadgeRenderer(Context context) { mContext = context; Resources res = context.getResources(); size = res.getDimensionPixelSize(R.dimen.badge_size); textSize = res.getDimensionPixelSize(R.dimen.badge_text_size); largeIconDrawer = new IconDrawer(res.getDimensionPixelSize(R.dimen.badge_small_padding)); smallIconDrawer = new IconDrawer(res.getDimensionPixelSize(R.dimen.badge_large_padding)); mSize = res.getDimensionPixelSize(R.dimen.badge_size); mLargeIconDrawer = new IconDrawer(res.getDimensionPixelSize(R.dimen.badge_small_padding)); mSmallIconDrawer = new IconDrawer(res.getDimensionPixelSize(R.dimen.badge_large_padding)); mTextPaint.setTextAlign(Paint.Align.CENTER); mTextPaint.setTextSize(textSize); mTextPaint.setTextSize(res.getDimensionPixelSize(R.dimen.badge_text_size)); // Measure the text height. Rect temp = new Rect(); mTextPaint.getTextBounds("0", 0, 1, temp); mTextHeight = temp.height(); Rect tempTextHeight = new Rect(); mTextPaint.getTextBounds("0", 0, 1, tempTextHeight); mTextHeight = tempTextHeight.height(); } /** * Draw a circle in the top right corner of the given bounds, and draw * {@link BadgeInfo#getNotificationCount()} on top of the circle. * @param palette The colors (based on the icon) to use for the badge. * @param badgeInfo Contains data to draw on the badge. * @param badgeInfo Contains data to draw on the badge. Could be null if we are animating out. * @param iconBounds The bounds of the icon being badged. * @param badgeScale The progress of the animation, from 0 to 1. */ public void draw(Canvas canvas, IconPalette palette, BadgeInfo badgeInfo, Rect iconBounds) { public void draw(Canvas canvas, IconPalette palette, @Nullable BadgeInfo badgeInfo, Rect iconBounds, float badgeScale) { mBackgroundPaint.setColor(palette.backgroundColor); mTextPaint.setColor(palette.textColor); mBackgroundRect.set(iconBounds.right - size, iconBounds.top, iconBounds.right, iconBounds.top + size); canvas.drawOval(mBackgroundRect, mBackgroundPaint); IconDrawer iconDrawer = badgeInfo.isIconLarge() ? largeIconDrawer : smallIconDrawer; Shader icon = badgeInfo.getNotificationIconForBadge(mContext, palette.backgroundColor, size, iconDrawer.mPadding); canvas.save(Canvas.MATRIX_SAVE_FLAG); // We draw the badge relative to its center. canvas.translate(iconBounds.right - mSize / 2, iconBounds.top + mSize / 2); canvas.scale(badgeScale, badgeScale); canvas.drawCircle(0, 0, mSize / 2, mBackgroundPaint); IconDrawer iconDrawer = badgeInfo != null && badgeInfo.isIconLarge() ? mLargeIconDrawer : mSmallIconDrawer; Shader icon = badgeInfo == null ? null : badgeInfo.getNotificationIconForBadge( mContext, palette.backgroundColor, mSize, iconDrawer.mPadding); if (icon != null) { // Draw the notification icon with padding. canvas.save(); canvas.translate(mBackgroundRect.left, mBackgroundRect.top); iconDrawer.drawIcon(icon, canvas); canvas.restore(); } else { // Draw the notification count. String notificationCount = String.valueOf(badgeInfo.getNotificationCount()); canvas.drawText(notificationCount, mBackgroundRect.centerX(), mBackgroundRect.centerY() + mTextHeight / 2, mTextPaint); String notificationCount = badgeInfo == null ? "0" : String.valueOf(badgeInfo.getNotificationCount()); canvas.drawText(notificationCount, 0, mTextHeight / 2, mTextPaint); } canvas.restore(); } /** Draws the notification icon with padding of a given size. */ Loading @@ -102,15 +100,15 @@ public class BadgeRenderer { public IconDrawer(int padding) { mPadding = padding; mCircleClipBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ALPHA_8); mCircleClipBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ALPHA_8); Canvas canvas = new Canvas(); canvas.setBitmap(mCircleClipBitmap); canvas.drawCircle(size / 2, size / 2, size / 2 - padding, mPaint); canvas.drawCircle(mSize / 2, mSize / 2, mSize / 2 - padding, mPaint); } public void drawIcon(Shader icon, Canvas canvas) { mPaint.setShader(icon); canvas.drawBitmap(mCircleClipBitmap, 0f, 0f, mPaint); canvas.drawBitmap(mCircleClipBitmap, -mSize / 2, -mSize / 2, mPaint); mPaint.setShader(null); } } Loading
src/com/android/launcher3/folder/FolderIcon.java +52 −3 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.graphics.drawable.Drawable; import android.os.Parcelable; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Property; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; Loading Loading @@ -130,6 +131,21 @@ public class FolderIcon extends FrameLayout implements FolderListener { private FolderBadgeInfo mBadgeInfo = new FolderBadgeInfo(); private BadgeRenderer mBadgeRenderer; private float mBadgeScale; private static final Property<FolderIcon, Float> BADGE_SCALE_PROPERTY = new Property<FolderIcon, Float>(Float.TYPE, "badgeScale") { @Override public Float get(FolderIcon folderIcon) { return folderIcon.mBadgeScale; } @Override public void set(FolderIcon folderIcon, Float value) { folderIcon.mBadgeScale = value; folderIcon.invalidate(); } }; public FolderIcon(Context context, AttributeSet attrs) { super(context, attrs); Loading Loading @@ -388,9 +404,26 @@ public class FolderIcon extends FrameLayout implements FolderListener { } public void setBadgeInfo(FolderBadgeInfo badgeInfo) { updateBadgeScale(mBadgeInfo.getNotificationCount(), badgeInfo.getNotificationCount()); mBadgeInfo = badgeInfo; } /** * Sets mBadgeScale to 1 or 0, animating if oldCount or newCount is 0 * (the badge is being added or removed). */ private void updateBadgeScale(int oldCount, int newCount) { boolean wasBadged = oldCount > 0; boolean isBadged = newCount > 0; float newBadgeScale = isBadged ? 1f : 0f; // Animate when a badge is first added or when it is removed. if ((wasBadged ^ isBadged) && isShown()) { ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, newBadgeScale).start(); } else { mBadgeScale = newBadgeScale; invalidate(); } } static class PreviewItemDrawingParams { PreviewItemDrawingParams(float transX, float transY, float scale, float overlayAlpha) { Loading Loading @@ -550,6 +583,14 @@ public class FolderIcon extends FrameLayout implements FolderListener { return basePreviewOffsetY - (getScaledRadius() - getRadius()); } /** * Returns the progress of the scale animation, where 0 means the scale is at 1f * and 1 means the scale is at ACCEPT_SCALE_FACTOR. */ float getScaleProgress() { return (mScale - 1f) / (ACCEPT_SCALE_FACTOR - 1f); } void invalidate() { int radius = getScaledRadius(); mClipPath.reset(); Loading Loading @@ -785,8 +826,10 @@ public class FolderIcon extends FrameLayout implements FolderListener { int offsetY = mBackground.getOffsetY(); int previewSize = (int) (mBackground.previewSize * mBackground.mScale); Rect bounds = new Rect(offsetX, offsetY, offsetX + previewSize, offsetY + previewSize); if (mBadgeInfo != null && mBadgeInfo.getNotificationCount() > 0) { mBadgeRenderer.draw(canvas, IconPalette.FOLDER_ICON_PALETTE, mBadgeInfo, bounds); if ((mBadgeInfo != null && mBadgeInfo.getNotificationCount() > 0) || mBadgeScale > 0) { // If we are animating to the accepting state, animate the badge out. float badgeScale = Math.max(0, mBadgeScale - mBackground.getScaleProgress()); mBadgeRenderer.draw(canvas, IconPalette.FOLDER_ICON_PALETTE, mBadgeInfo, bounds, badgeScale); } } Loading Loading @@ -939,14 +982,20 @@ public class FolderIcon extends FrameLayout implements FolderListener { @Override public void onAdd(ShortcutInfo item) { int oldCount = mBadgeInfo.getNotificationCount(); mBadgeInfo.addBadgeInfo(mLauncher.getPopupDataProvider().getBadgeInfoForItem(item)); int newCount = mBadgeInfo.getNotificationCount(); updateBadgeScale(oldCount, newCount); invalidate(); requestLayout(); } @Override public void onRemove(ShortcutInfo item) { int oldCount = mBadgeInfo.getNotificationCount(); mBadgeInfo.subtractBadgeInfo(mLauncher.getPopupDataProvider().getBadgeInfoForItem(item)); int newCount = mBadgeInfo.getNotificationCount(); updateBadgeScale(oldCount, newCount); invalidate(); requestLayout(); } Loading