1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.mail.bitmap; 17 18 import android.content.res.Resources; 19 import android.graphics.Bitmap; 20 import android.graphics.BitmapFactory; 21 import android.graphics.Canvas; 22 import android.graphics.Paint; 23 import android.graphics.Paint.Align; 24 import android.graphics.Rect; 25 import android.graphics.Typeface; 26 27 import com.android.mail.R; 28 29 /** 30 * A contact drawable with the default avatar as a letter tile. 31 */ 32 public class ContactDrawable extends AbstractAvatarDrawable { 33 /** Letter tile */ 34 private ColorPicker mTileColorPicker; 35 36 /** Reusable components to avoid new allocations */ 37 private static int sTileLetterFontSize; 38 private static int sTileFontColor; 39 private static Bitmap DEFAULT_AVATAR; 40 private static final Paint sPaint = new Paint(); 41 private static final Rect sRect = new Rect(); 42 private static final char[] sFirstChar = new char[1]; 43 ContactDrawable(final Resources res)44 public ContactDrawable(final Resources res) { 45 super(res); 46 47 if (sTileLetterFontSize == 0) { 48 sTileLetterFontSize = res.getDimensionPixelSize(R.dimen.tile_letter_font_size_small); 49 sTileFontColor = res.getColor(R.color.letter_tile_font_color); 50 DEFAULT_AVATAR = BitmapFactory.decodeResource(res, R.drawable.ic_anonymous_avatar_40dp); 51 52 sPaint.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL)); 53 sPaint.setTextAlign(Align.CENTER); 54 sPaint.setAntiAlias(true); 55 } 56 } 57 58 /** 59 * Sets the {@link ColorPicker} for the background tile used in letter avatars. 60 * @param colorPicker 61 */ setTileColorPicker(ColorPicker colorPicker)62 public void setTileColorPicker(ColorPicker colorPicker) { 63 mTileColorPicker = colorPicker; 64 } 65 66 /** 67 * Returns the color picker for the background tile used in the letter avatars. 68 * If none was set, initializes a simple {@link ColorPicker.PaletteColorPicker} first. 69 * @return non-null color picker. 70 */ getTileColorPicker()71 public ColorPicker getTileColorPicker() { 72 if (mTileColorPicker == null) { 73 mTileColorPicker = new ColorPicker.PaletteColorPicker(mResources); 74 } 75 return mTileColorPicker; 76 } 77 78 @Override drawDefaultAvatar(Canvas canvas)79 protected void drawDefaultAvatar(Canvas canvas) { 80 // Draw letter tile as default 81 drawLetterTile(canvas); 82 } 83 drawLetterTile(final Canvas canvas)84 private void drawLetterTile(final Canvas canvas) { 85 if (mContactRequest == null) { 86 return; 87 } 88 89 final Rect bounds = getBounds(); 90 91 // Draw background color. 92 final String email = mContactRequest.getEmail(); 93 // The email should already have been normalized by the ContactRequest. 94 sPaint.setColor(getTileColorPicker().pickColor(email)); 95 sPaint.setAlpha(mBitmapPaint.getAlpha()); 96 drawCircle(canvas, bounds, sPaint); 97 98 // Draw letter/digit or generic avatar. 99 final String displayName = mContactRequest.getDisplayName(); 100 final char firstChar = displayName.charAt(0); 101 if (isEnglishLetterOrDigit(firstChar)) { 102 // Draw letter or digit. 103 sFirstChar[0] = Character.toUpperCase(firstChar); 104 sPaint.setTextSize(sTileLetterFontSize); 105 sPaint.getTextBounds(sFirstChar, 0, 1, sRect); 106 sPaint.setColor(sTileFontColor); 107 canvas.drawText(sFirstChar, 0, 1, bounds.centerX(), 108 bounds.centerY() + sRect.height() / 2, sPaint); 109 } else { 110 drawBitmap(DEFAULT_AVATAR, DEFAULT_AVATAR.getWidth(), DEFAULT_AVATAR.getHeight(), 111 canvas); 112 } 113 } 114 isEnglishLetterOrDigit(final char c)115 private static boolean isEnglishLetterOrDigit(final char c) { 116 return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9'); 117 } 118 } 119