1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-30 13:12:25 -05:00

Merge pull request #353 from sfuhrm/gmail-style-user-pics

Gmail style user pics, 2nd try

* sfuhrm/gmail-style-user-pics:
  Changed the fallback char from 'K' to '?'. The riddler was here ;).
  Using Android proposed colors as contact color palette now: http://developer.android.com/design/style/color.html
  Fixed NPE found by blackbox87 ... thanks pal!
  Added more finer characters as proposed by cketti
  Caching also the calculated anonymous bitmap as proposed by maniac103. This removes a lot of code for special handling unknown contacts.
  Bugfix for negative modulo result indexing the palette array
  Changed hash based color calc to a hash indexed palette as discussed in the pull request.
  GMail-app-style generated colorful one-letter contact pictures for pictureless contacts

Conflicts:
	src/com/fsck/k9/activity/misc/ContactPictureLoader.java
	src/com/fsck/k9/fragment/MessageListFragment.java
This commit is contained in:
Jesse Vincent 2013-07-30 21:43:21 -04:00
commit 2ba84bceaa
2 changed files with 54 additions and 85 deletions

View File

@ -33,17 +33,6 @@ public class ContactPictureLoader {
*/ */
private static final int PICTURE_SIZE = 40; private static final int PICTURE_SIZE = 40;
/**
* Maximum number of email addresses to store in {@link #mUnknownContactsCache}.
*/
private static final int MAX_UNKNOWN_CONTACTS = 1000;
/**
* Used as lightweight dummy value for entries in {@link #mUnknownContactsCache}.
*/
private static final int[] DUMMY_INT_ARRAY = new int[0];
private ContentResolver mContentResolver; private ContentResolver mContentResolver;
private Resources mResources; private Resources mResources;
private Contacts mContactsHelper; private Contacts mContactsHelper;
@ -55,18 +44,20 @@ public class ContactPictureLoader {
private final LruCache<String, Bitmap> mBitmapCache; private final LruCache<String, Bitmap> mBitmapCache;
/** /**
* LRU cache of email addresses that don't belong to a contact we have a picture for. * @see <a href="http://developer.android.com/design/style/color.html">Color palette used</a>
*
* <p>
* We don't store the default picture for unknown contacts or contacts without a picture in
* {@link #mBitmapCache}, because that would lead to an unnecessarily complex implementation of
* the {@code LruCache.sizeOf()} method. Instead, we save the email addresses we know don't
* belong to one of our contacts with a picture. Knowing this, we can avoid querying the
* contacts database for those addresses and immediately return the default picture.
* </p>
*/ */
private final LruCache<String, int[]> mUnknownContactsCache; private final static int CONTACT_DUMMY_COLORS_ARGB[] = {
0xff33B5E5,
0xffAA66CC,
0xff99CC00,
0xffFFBB33,
0xffFF4444,
0xff0099CC,
0xff9933CC,
0xff669900,
0xffFF8800,
0xffCC0000
};
public ContactPictureLoader(Context context, int defaultPictureResource) { public ContactPictureLoader(Context context, int defaultPictureResource) {
Context appContext = context.getApplicationContext(); Context appContext = context.getApplicationContext();
@ -95,8 +86,6 @@ public class ContactPictureLoader {
return bitmap.getRowBytes() * bitmap.getHeight(); return bitmap.getRowBytes() * bitmap.getHeight();
} }
}; };
mUnknownContactsCache = new LruCache<String, int[]>(MAX_UNKNOWN_CONTACTS);
} }
/** /**
@ -125,10 +114,6 @@ public class ContactPictureLoader {
if (bitmap != null) { if (bitmap != null) {
// The picture was found in the bitmap cache // The picture was found in the bitmap cache
badge.setImageBitmap(bitmap); badge.setImageBitmap(bitmap);
} else if (isEmailInUnknownContactsCache(email)) {
// This email address doesn't belong to a contact we have a picture for. Use the
// default picture.
badge.setImageBitmap(calculateFallbackBitmap(address));
} else if (cancelPotentialWork(email, badge)) { } else if (cancelPotentialWork(email, badge)) {
// Query the contacts database in a background thread and try to load the contact // Query the contacts database in a background thread and try to load the contact
// picture, if there is one. // picture, if there is one.
@ -146,11 +131,7 @@ public class ContactPictureLoader {
private int calcUnknownContactColor(Address address) { private int calcUnknownContactColor(Address address) {
int val = address.getAddress().toLowerCase().hashCode(); int val = address.getAddress().toLowerCase().hashCode();
int rgb = int rgb = CONTACT_DUMMY_COLORS_ARGB[Math.abs(val) % CONTACT_DUMMY_COLORS_ARGB.length];
(0xff) << 24 |
(~val & 0xff) << 16 |
(val & 0xff) << 8 |
(val>>>8 & 0xff);
return rgb; return rgb;
} }
@ -163,7 +144,7 @@ public class ContactPictureLoader {
letter = m.group(1).toUpperCase(); letter = m.group(1).toUpperCase();
} }
return letter.length() == 0 ? 'K' : letter.charAt(0); return letter.length() == 0 ? '?' : letter.charAt(0);
} }
/** Calculates a bitmap with a color and a capital letter for /** Calculates a bitmap with a color and a capital letter for
@ -183,8 +164,7 @@ public class ContactPictureLoader {
paint.setAntiAlias(true); paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL); paint.setStyle(Paint.Style.FILL);
paint.setARGB(255, 255, 255, 255); paint.setARGB(255, 255, 255, 255);
paint.setFakeBoldText(true); paint.setTextSize(mPictureSizeInPx * 3 / 4); // just scale this down a bit
paint.setTextSize(mPictureSizeInPx);
Rect rect = new Rect(); Rect rect = new Rect();
paint.getTextBounds(letter, 0, 1, rect); paint.getTextBounds(letter, 0, 1, rect);
float width = paint.measureText(letter); float width = paint.measureText(letter);
@ -205,16 +185,6 @@ public class ContactPictureLoader {
return mBitmapCache.get(key); return mBitmapCache.get(key);
} }
private void addEmailToUnknownContactsCache(String key) {
if (!isEmailInUnknownContactsCache(key)) {
mUnknownContactsCache.put(key, DUMMY_INT_ARRAY);
}
}
private boolean isEmailInUnknownContactsCache(String key) {
return mUnknownContactsCache.get(key) != null;
}
/** /**
* Checks if a {@code ContactPictureRetrievalTask} was already created to load the contact * Checks if a {@code ContactPictureRetrievalTask} was already created to load the contact
* picture for the supplied email address. * picture for the supplied email address.
@ -314,9 +284,8 @@ public class ContactPictureLoader {
if (bitmap == null) { if (bitmap == null) {
bitmap = calculateFallbackBitmap(mAddress); bitmap = calculateFallbackBitmap(mAddress);
// Remember that we don't have a contact picture for this email address // Remember that we don't have a contact picture for this email address
addEmailToUnknownContactsCache(email); addBitmapToCache(email, bitmap);
} else { } else {
// Save the picture of the contact with that email address in the memory cache // Save the picture of the contact with that email address in the memory cache
addBitmapToCache(email, bitmap); addBitmapToCache(email, bitmap);

View File

@ -1923,8 +1923,8 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
holder.position = cursor.getPosition(); holder.position = cursor.getPosition();
if (holder.contactBadge != null) { if (holder.contactBadge != null) {
holder.contactBadge.assignContactFromEmail(counterpartyAddress.getAddress(), true);
if (counterpartyAddress != null) { if (counterpartyAddress != null) {
holder.contactBadge.assignContactFromEmail(counterpartyAddress.getAddress(), true);
/* /*
* At least in Android 2.2 a different background + padding is used when no * At least in Android 2.2 a different background + padding is used when no
* email address is available. ListView reuses the views but QuickContactBadge * email address is available. ListView reuses the views but QuickContactBadge