diff options
author | Tony Wickham <twickham@google.com> | 2017-01-31 10:49:18 -0800 |
---|---|---|
committer | Tony Wickham <twickham@google.com> | 2017-02-07 09:48:43 -0800 |
commit | a799bed8038ae97ee8985bc4475756391f7f4f0c (patch) | |
tree | 91e37258f262b8cd147272b3ad779d084ffcb999 /src/com/android/launcher3/badge | |
parent | e1fa0145d36fbefeb397f952cba2689ce537d786 (diff) | |
download | packages_apps_Trebuchet-a799bed8038ae97ee8985bc4475756391f7f4f0c.tar.gz packages_apps_Trebuchet-a799bed8038ae97ee8985bc4475756391f7f4f0c.tar.bz2 packages_apps_Trebuchet-a799bed8038ae97ee8985bc4475756391f7f4f0c.zip |
Show notification icon in place of "1" in badge.
- When notifications update, add the NotificationInfo to the
BadgeInfo if there is only one for an app. BadgeRenderer
will use the NotificationInfo to get the icon to draw.
- When retrieving the icon from the NotificationInfo, we draw
it into a shader (similar to MaskableIconDrawable), which is
rendered by BadgeRenderer.
- For now, we only use the notification icon if it is large.
Bug: 34839959
Bug: 32410600
Bug: 33553066
Change-Id: I31851804008dd15bab75d2759441187830c3265e
Diffstat (limited to 'src/com/android/launcher3/badge')
-rw-r--r-- | src/com/android/launcher3/badge/BadgeInfo.java | 62 | ||||
-rw-r--r-- | src/com/android/launcher3/badge/BadgeRenderer.java | 63 |
2 files changed, 115 insertions, 10 deletions
diff --git a/src/com/android/launcher3/badge/BadgeInfo.java b/src/com/android/launcher3/badge/BadgeInfo.java index 77355c75e..532396cdd 100644 --- a/src/com/android/launcher3/badge/BadgeInfo.java +++ b/src/com/android/launcher3/badge/BadgeInfo.java @@ -16,6 +16,14 @@ package com.android.launcher3.badge; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapShader; +import android.graphics.Canvas; +import android.graphics.Shader; +import android.graphics.drawable.Drawable; +import android.support.annotation.Nullable; + import com.android.launcher3.notification.NotificationInfo; import com.android.launcher3.util.PackageUserKey; @@ -29,12 +37,22 @@ public class BadgeInfo { /** Used to link this BadgeInfo to icons on the workspace and all apps */ private PackageUserKey mPackageUserKey; + /** * The keys of the notifications that this badge represents. These keys can later be * used to retrieve {@link NotificationInfo}'s. */ private List<String> mNotificationKeys; + /** This will only be initialized if the badge should display the notification icon. */ + private NotificationInfo mNotificationInfo; + + /** + * When retrieving the notification icon, we draw it into this shader, which can be clipped + * as necessary when drawn in a badge. + */ + private Shader mNotificationIcon; + public BadgeInfo(PackageUserKey packageUserKey) { mPackageUserKey = packageUserKey; mNotificationKeys = new ArrayList<>(); @@ -65,15 +83,55 @@ public class BadgeInfo { return mNotificationKeys.size(); } + public void setNotificationToShow(@Nullable NotificationInfo notificationInfo) { + mNotificationInfo = notificationInfo; + mNotificationIcon = null; + } + + public boolean hasNotificationToShow() { + return mNotificationInfo != null; + } + + /** + * Returns a shader to set on a Paint that will draw the notification icon in a badge. + * + * The shader is cached until {@link #setNotificationToShow(NotificationInfo)} is called. + */ + public @Nullable Shader getNotificationIconForBadge(Context context, int badgeColor, + int badgeSize, int badgePadding) { + if (mNotificationInfo == null) { + return null; + } + if (mNotificationIcon == null) { + Drawable icon = mNotificationInfo.getIconForBackground(context, badgeColor) + .getConstantState().newDrawable(); + int iconSize = badgeSize - badgePadding * 2; + icon.setBounds(0, 0, iconSize, iconSize); + Bitmap iconBitmap = Bitmap.createBitmap(badgeSize, badgeSize, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(iconBitmap); + canvas.translate(badgePadding, badgePadding); + icon.draw(canvas); + mNotificationIcon = new BitmapShader(iconBitmap, Shader.TileMode.CLAMP, + Shader.TileMode.CLAMP); + } + return mNotificationIcon; + } + + public boolean isIconLarge() { + return mNotificationInfo != null && mNotificationInfo.isIconLarge(); + } + /** * Whether newBadge represents the same PackageUserKey as this badge, and icons with * this badge should be invalidated. So, for instance, if a badge has 3 notifications * and one of those notifications is updated, this method should return false because * the badge still says "3" and the contents of those notifications are only retrieved - * upon long-click. This method always returns true when adding or removing notifications. + * upon long-click. This method always returns true when adding or removing notifications, + * or if the badge has a notification icon to show. */ public boolean shouldBeInvalidated(BadgeInfo newBadge) { return mPackageUserKey.equals(newBadge.mPackageUserKey) - && getNotificationCount() != newBadge.getNotificationCount(); + && (getNotificationCount() != newBadge.getNotificationCount() + || hasNotificationToShow()); } } diff --git a/src/com/android/launcher3/badge/BadgeRenderer.java b/src/com/android/launcher3/badge/BadgeRenderer.java index 787ee724e..4bb09546f 100644 --- a/src/com/android/launcher3/badge/BadgeRenderer.java +++ b/src/com/android/launcher3/badge/BadgeRenderer.java @@ -16,11 +16,16 @@ package com.android.launcher3.badge; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; +import android.graphics.Shader; +import com.android.launcher3.R; import com.android.launcher3.graphics.IconPalette; /** @@ -31,15 +36,22 @@ 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 Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final int mTextHeight; - public BadgeRenderer(int size, int textSize) { - this.size = size; - this.textSize = textSize; + 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)); mTextPaint.setTextAlign(Paint.Align.CENTER); mTextPaint.setTextSize(textSize); // Measure the text height. @@ -61,10 +73,45 @@ public class BadgeRenderer { mBackgroundRect.set(iconBounds.right - size, iconBounds.top, iconBounds.right, iconBounds.top + size); canvas.drawOval(mBackgroundRect, mBackgroundPaint); - String notificationCount = String.valueOf(badgeInfo.getNotificationCount()); - canvas.drawText(notificationCount, - mBackgroundRect.centerX(), - mBackgroundRect.centerY() + mTextHeight / 2, - mTextPaint); + IconDrawer iconDrawer = badgeInfo.isIconLarge() ? largeIconDrawer : smallIconDrawer; + Shader icon = badgeInfo.getNotificationIconForBadge(mContext, palette.backgroundColor, size, + 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); + } + } + + /** Draws the notification icon with padding of a given size. */ + private class IconDrawer { + + private final int mPadding; + private final Bitmap mCircleClipBitmap; + private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | + Paint.FILTER_BITMAP_FLAG); + + public IconDrawer(int padding) { + mPadding = padding; + mCircleClipBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ALPHA_8); + Canvas canvas = new Canvas(); + canvas.setBitmap(mCircleClipBitmap); + canvas.drawCircle(size / 2, size / 2, size / 2 - padding, mPaint); + } + + public void drawIcon(Shader icon, Canvas canvas) { + mPaint.setShader(icon); + canvas.drawBitmap(mCircleClipBitmap, 0f, 0f, mPaint); + mPaint.setShader(null); + } } } |