Nice color default icons for bookmarks
This commit is contained in:
parent
3b8f85a86a
commit
0e55c653b0
@ -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<Bitmap> faviconForUrl(@NonNull final String url,
|
||||
@NonNull final Bitmap defaultFavicon,
|
||||
@NonNull final String title,
|
||||
final boolean allowGoogleService) {
|
||||
return Single.create(new SingleAction<Bitmap>() {
|
||||
@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);
|
||||
|
@ -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<Bitmap>() {
|
||||
|
@ -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;
|
||||
|
@ -9,8 +9,8 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/faviconBookmark"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_width="@dimen/bookmark_item_icon_size"
|
||||
android:layout_height="@dimen/bookmark_item_icon_size"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:contentDescription="Favicon"
|
||||
|
@ -1,5 +1,5 @@
|
||||
{"url": "https://twitter.com/RestainoAnthony", "title": "Contact Me", "folder": "", "order": 0}
|
||||
{"url": "https://www.facebook.com/", "title": "Facebook", "folder": "", "order": 2}
|
||||
{"url": "https://twitter.com", "title": "Twitter", "folder": "", "order": 3}
|
||||
{"url": "https://www.google.com/", "title": "Google", "folder": "", "order": 4}
|
||||
{"url": "https://www.yahoo.com/", "title": "Yahoo", "folder": "", "order": 5}
|
||||
{"url": "https://www.facebook.com/", "title": "Facebook", "folder": "", "order": 1}
|
||||
{"url": "https://twitter.com", "title": "Twitter", "folder": "", "order": 2}
|
||||
{"url": "https://www.google.com/", "title": "Google", "folder": "", "order": 3}
|
||||
{"url": "https://www.wikipedia.org/", "title": "Wikipedia", "folder": "", "order": 4}
|
||||
|
@ -37,4 +37,9 @@
|
||||
|
||||
<color name="error_red">#F44336</color>
|
||||
|
||||
<color name="bookmark_default_blue">#2196F3</color>
|
||||
<color name="bookmark_default_green">#4CAF50</color>
|
||||
<color name="bookmark_default_red">#EF5350</color>
|
||||
<color name="bookmark_default_orange">#FF9800</color>
|
||||
|
||||
</resources>
|
@ -10,4 +10,6 @@
|
||||
<dimen name="default_padding">8dp</dimen>
|
||||
<dimen name="extra_padding">16dp</dimen>
|
||||
|
||||
<dimen name="bookmark_item_icon_size">24dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user