From 0e55c653b0d383609179b126b0e73244e444c8f0 Mon Sep 17 00:00:00 2001 From: anthony restaino Date: Sun, 11 Jun 2017 16:56:34 -0400 Subject: [PATCH] Nice color default icons for bookmarks --- .../lightning/favicon/FaviconModel.java | 36 +++++++--- .../lightning/fragment/BookmarksFragment.java | 2 +- .../lightning/utils/DrawableUtils.java | 69 +++++++++++++++++++ .../main/res/layout/bookmark_list_item.xml | 4 +- app/src/main/res/raw/default_bookmarks.dat | 8 +-- app/src/main/res/values/colors.xml | 5 ++ app/src/main/res/values/dimens.xml | 2 + 7 files changed, 109 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/acr/browser/lightning/favicon/FaviconModel.java b/app/src/main/java/acr/browser/lightning/favicon/FaviconModel.java index 02c7ee5..3dbfaad 100644 --- a/app/src/main/java/acr/browser/lightning/favicon/FaviconModel.java +++ b/app/src/main/java/acr/browser/lightning/favicon/FaviconModel.java @@ -3,6 +3,7 @@ package acr.browser.lightning.favicon; import android.app.Application; import android.graphics.Bitmap; import android.net.Uri; +import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; @@ -22,6 +23,8 @@ import java.io.IOException; import javax.inject.Inject; import javax.inject.Singleton; +import acr.browser.lightning.R; +import acr.browser.lightning.utils.DrawableUtils; import acr.browser.lightning.utils.FileUtils; import acr.browser.lightning.utils.Preconditions; import acr.browser.lightning.utils.Utils; @@ -44,10 +47,13 @@ public class FaviconModel { } }; + private final int mBookmarkIconSize; + @Inject FaviconModel(@NonNull Application application) { mImageFetcher = new ImageFetcher(); mApplication = application; + mBookmarkIconSize = mApplication.getResources().getDimensionPixelSize(R.dimen.bookmark_item_icon_size); } /** @@ -68,6 +74,16 @@ public class FaviconModel { } } + @NonNull + private Bitmap getDefaultBitmapForCharacter(@NonNull Character character) { + @ColorInt int defaultFaviconColor = DrawableUtils.characterToColorHash(character, mApplication); + + return DrawableUtils.getRoundedLetterImage(character, + mBookmarkIconSize, + mBookmarkIconSize, + defaultFaviconColor); + } + /** * Adds a bitmap to the memory cache * for the given URL. @@ -106,18 +122,15 @@ public class FaviconModel { * Retrieves the favicon for a URL, * may be from network or cache. * - * @param url the URL that we should retrieve the + * @param url The URL that we should retrieve the * favicon for. - * @param defaultFavicon the default favicon if no - * favicon is found. - * @param allowGoogleService true to allow grabbing favicons - * from Google, false otherwise. - * @return an observable that emits a bitmap if one is found, - * or the default if none was found. + * @param title The title for the web page. + * @param allowGoogleService True to allow grabbing favicons + * from Google, false otherwise. @return an observable that emits a bitmap if one is found, */ @NonNull public Single faviconForUrl(@NonNull final String url, - @NonNull final Bitmap defaultFavicon, + @NonNull final String title, final boolean allowGoogleService) { return Single.create(new SingleAction() { @Override @@ -126,7 +139,7 @@ public class FaviconModel { if (uri == null) { - Bitmap newFavicon = Utils.padFavicon(defaultFavicon); + Bitmap newFavicon = Utils.padFavicon(getDefaultBitmapForCharacter('?')); subscriber.onItem(newFavicon); subscriber.onComplete(); @@ -134,6 +147,9 @@ public class FaviconModel { return; } + Character firstTitleCharacter = !title.isEmpty() ? title.charAt(0) : '?'; + + File faviconCacheFile = createFaviconCacheFile(mApplication, uri); Bitmap favicon = getFaviconFromMemCache(url); @@ -168,7 +184,7 @@ public class FaviconModel { // } // if (favicon == null) { - favicon = defaultFavicon; + favicon = getDefaultBitmapForCharacter(firstTitleCharacter); // } Bitmap newFavicon = Utils.padFavicon(favicon); diff --git a/app/src/main/java/acr/browser/lightning/fragment/BookmarksFragment.java b/app/src/main/java/acr/browser/lightning/fragment/BookmarksFragment.java index b447dbd..7668c8e 100644 --- a/app/src/main/java/acr/browser/lightning/fragment/BookmarksFragment.java +++ b/app/src/main/java/acr/browser/lightning/fragment/BookmarksFragment.java @@ -537,7 +537,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, Subscription oldSubscription = mFaviconFetchSubscriptions.get(url); SubscriptionUtils.safeUnsubscribe(oldSubscription); - final Subscription faviconSubscription = mFaviconModel.faviconForUrl(url, mWebpageBitmap, true) + final Subscription faviconSubscription = mFaviconModel.faviconForUrl(url, web.getTitle(), true) .subscribeOn(Schedulers.worker()) .observeOn(Schedulers.main()) .subscribe(new SingleOnSubscribe() { diff --git a/app/src/main/java/acr/browser/lightning/utils/DrawableUtils.java b/app/src/main/java/acr/browser/lightning/utils/DrawableUtils.java index 19e426c..259ce15 100644 --- a/app/src/main/java/acr/browser/lightning/utils/DrawableUtils.java +++ b/app/src/main/java/acr/browser/lightning/utils/DrawableUtils.java @@ -1,7 +1,9 @@ package acr.browser.lightning.utils; +import android.app.Application; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; @@ -9,12 +11,17 @@ import android.graphics.RectF; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Build; +import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.content.ContextCompat; import android.view.View; +import acr.browser.lightning.R; + public class DrawableUtils { + @NonNull public static Bitmap getRoundedNumberImage(int number, int width, int height, int color, int thickness) { String text; @@ -56,6 +63,68 @@ public class DrawableUtils { return image; } + /** + * Creates a rounded square of a certain color with + * a character imprinted in white on it. + * + * @param character the character to write on the image. + * @param width the width of the final image. + * @param height the height of the final image. + * @param color the background color of the rounded square. + * @return a valid bitmap of a rounded square with a character on it. + */ + @NonNull + public static Bitmap getRoundedLetterImage(@NonNull Character character, int width, int height, int color) { + Bitmap image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(image); + Paint paint = new Paint(); + paint.setColor(color); + Typeface boldText = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD); + paint.setTypeface(boldText); + paint.setTextSize(Utils.dpToPx(14)); + paint.setAntiAlias(true); + paint.setTextAlign(Paint.Align.CENTER); + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); + + int radius = Utils.dpToPx(2); + + RectF outer = new RectF(0, 0, canvas.getWidth(), canvas.getHeight()); + canvas.drawRoundRect(outer, radius, radius, paint); + + int xPos = (canvas.getWidth() / 2); + int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2)); + + paint.setColor(Color.WHITE); + canvas.drawText(character.toString(), xPos, yPos, paint); + + return image; + } + + /** + * Hashes a character to one of four colors: + * blue, green, red, or orange. + * + * @param character the character to hash. + * @param app the application needed to get the color. + * @return one of the above colors, or black something goes wrong. + */ + @ColorInt + public static int characterToColorHash(@NonNull Character character, @NonNull Application app) { + int smallHash = Character.getNumericValue(character) % 4; + switch (Math.abs(smallHash)) { + case 0: + return ContextCompat.getColor(app, R.color.bookmark_default_blue); + case 1: + return ContextCompat.getColor(app, R.color.bookmark_default_green); + case 2: + return ContextCompat.getColor(app, R.color.bookmark_default_red); + case 3: + return ContextCompat.getColor(app, R.color.bookmark_default_orange); + default: + return Color.BLACK; + } + } + public static int mixColor(float fraction, int startValue, int endValue) { int startA = (startValue >> 24) & 0xff; diff --git a/app/src/main/res/layout/bookmark_list_item.xml b/app/src/main/res/layout/bookmark_list_item.xml index 17bf88a..874b39f 100644 --- a/app/src/main/res/layout/bookmark_list_item.xml +++ b/app/src/main/res/layout/bookmark_list_item.xml @@ -9,8 +9,8 @@ #F44336 + #2196F3 + #4CAF50 + #EF5350 + #FF9800 + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 5059ea6..d40476a 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -10,4 +10,6 @@ 8dp 16dp + 24dp +