2014-04-16 2 views
24

나는 그들이 어떻게 생성되는지 궁금했고, 앱을 열 때마다 생성되는지 또는 저장 (캐싱)되는지 궁금해했다.컬러 박스 글자 a la Gmail

그냥 캔버스 (프로그래밍 방식)이거나 XML을 사용하고 있습니까?

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> 
    <size android:width="1px" android:height="1dp"/> 
    <solid android:color="#FFFFF5EE/> 
</shape> 

답변

45

내가 응용 프로그램을 열거 나 (캐시)

리틀 열 A는, 약간의 열 B.가있다 저장되어 매번 생성됩니다 다음 이런 식으로 뭔가 및 프로그래밍 그들은 편지를 추가 작은 캐시가 사용되었지만 당신이 생각하는 것이 아닙니다. 각 타일은 4 조각으로 나눌 수 있으며, 캐시는 특정 위치를 검색하는 데 사용됩니다. 배경이 밝아지면 색상은 동일한 이메일 주소 (또는 키)가 항상 같은 색상으로 매핑되도록 String.hashCode을 사용하여 매핑됩니다. 그러나 실제 편지는 Canvas.drawText을 사용하여 그려집니다. "E

<!-- All of the possible tile background colors --> 
<array name="letter_tile_colors"> 
    <item>#f16364</item> 
    <item>#f58559</item> 
    <item>#f9a43e</item> 
    <item>#e4c62e</item> 
    <item>#67bf74</item> 
    <item>#59a2be</item> 
    <item>#2093cd</item> 
    <item>#ad62a7</item> 
</array> 

<!-- The default letter tile text size --> 
<dimen name="tile_letter_font_size">33sp</dimen> 
<!-- The deafult tile size --> 
<dimen name="letter_tile_size">64dp</dimen> 

구현"T "의

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    final Resources res = getResources(); 
    final int tileSize = res.getDimensionPixelSize(R.dimen.letter_tile_size); 

    final LetterTileProvider tileProvider = new LetterTileProvider(this); 
    final Bitmap letterTile = tileProvider.getLetterTile("name", "key", tileSize, tileSize); 

    getActionBar().setIcon(new BitmapDrawable(getResources(), letterTile)); 
} 

결과 : 여기

/** 
* Used to create a {@link Bitmap} that contains a letter used in the English 
* alphabet or digit, if there is no letter or digit available, a default image 
* is shown instead 
*/ 
public class LetterTileProvider { 

    /** The number of available tile colors (see R.array.letter_tile_colors) */ 
    private static final int NUM_OF_TILE_COLORS = 8; 

    /** The {@link TextPaint} used to draw the letter onto the tile */ 
    private final TextPaint mPaint = new TextPaint(); 
    /** The bounds that enclose the letter */ 
    private final Rect mBounds = new Rect(); 
    /** The {@link Canvas} to draw on */ 
    private final Canvas mCanvas = new Canvas(); 
    /** The first char of the name being displayed */ 
    private final char[] mFirstChar = new char[1]; 

    /** The background colors of the tile */ 
    private final TypedArray mColors; 
    /** The font size used to display the letter */ 
    private final int mTileLetterFontSize; 
    /** The default image to display */ 
    private final Bitmap mDefaultBitmap; 

    /** 
    * Constructor for <code>LetterTileProvider</code> 
    * 
    * @param context The {@link Context} to use 
    */ 
    public LetterTileProvider(Context context) { 
     final Resources res = context.getResources(); 

     mPaint.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL)); 
     mPaint.setColor(Color.WHITE); 
     mPaint.setTextAlign(Align.CENTER); 
     mPaint.setAntiAlias(true); 

     mColors = res.obtainTypedArray(R.array.letter_tile_colors); 
     mTileLetterFontSize = res.getDimensionPixelSize(R.dimen.tile_letter_font_size); 

     mDefaultBitmap = BitmapFactory.decodeResource(res, android.R.drawable.sym_def_app_icon); 
    } 

    /** 
    * @param displayName The name used to create the letter for the tile 
    * @param key The key used to generate the background color for the tile 
    * @param width The desired width of the tile 
    * @param height The desired height of the tile 
    * @return A {@link Bitmap} that contains a letter used in the English 
    *   alphabet or digit, if there is no letter or digit available, a 
    *   default image is shown instead 
    */ 
    public Bitmap getLetterTile(String displayName, String key, int width, int height) { 
     final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
     final char firstChar = displayName.charAt(0); 

     final Canvas c = mCanvas; 
     c.setBitmap(bitmap); 
     c.drawColor(pickColor(key)); 

     if (isEnglishLetterOrDigit(firstChar)) { 
      mFirstChar[0] = Character.toUpperCase(firstChar); 
      mPaint.setTextSize(mTileLetterFontSize); 
      mPaint.getTextBounds(mFirstChar, 0, 1, mBounds); 
      c.drawText(mFirstChar, 0, 1, 0 + width/2, 0 + height/2 
        + (mBounds.bottom - mBounds.top)/2, mPaint); 
     } else { 
      c.drawBitmap(mDefaultBitmap, 0, 0, null); 
     } 
     return bitmap; 
    } 

    /** 
    * @param c The char to check 
    * @return True if <code>c</code> is in the English alphabet or is a digit, 
    *   false otherwise 
    */ 
    private static boolean isEnglishLetterOrDigit(char c) { 
     return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9'; 
    } 

    /** 
    * @param key The key used to generate the tile color 
    * @return A new or previously chosen color for <code>key</code> used as the 
    *   tile background color 
    */ 
    private int pickColor(String key) { 
     // String.hashCode() is not supposed to change across java versions, so 
     // this should guarantee the same key always maps to the same color 
     final int color = Math.abs(key.hashCode()) % NUM_OF_TILE_COLORS; 
     try { 
      return mColors.getColor(color, Color.BLACK); 
     } finally { 
      mColors.recycle(); 
     } 
    } 

} 

기본 색상과 텍스트 크기 : 여기

은 예입니다 ","S ","T "
: 우리는 다음과 같이 우리가 getLetterTile 기능을 수정할 수있는 원형 아이콘을 생성 할 경우, @ adneal의 응답에까지 구축

T

E

S

T

+4

해당 코드의 라이센스는 무엇입니까? –

+0

열쇠는 무엇이되어야합니까? – SMahdiS

+0

코드가 [메일 앱에서 파생 된 것 같습니다] (https://android.googlesource.com/platform/packages/apps/UnifiedEmail/+/184ec73/src/com/android/mail/photomanager/LetterTileProvider.java) __Apache License 2.0__에 의거하여 라이센스가 부여됩니다. – Phil

0

:

public Bitmap getLetterTile(String displayName, String key, int width, int height, boolean round) { 
    final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
    final char firstChar = displayName.charAt(0); 

    final Canvas c = mCanvas; 
    c.setBitmap(bitmap); 

    if (round) { 
     Paint paint = new Paint(); 
     paint.setStyle(Paint.Style.FILL); 
     paint.setColor(pickColor(key)); 
     c.drawCircle(width/2, height/2 , width/2, paint); 
    } else { 
     c.drawColor(pickColor(key)); 
    } 

    if (isEnglishLetterOrDigit(firstChar)) { 
     mFirstChar[0] = Character.toUpperCase(firstChar); 
     mPaint.setTextSize(mTileLetterFontSize); 
     mPaint.getTextBounds(mFirstChar, 0, 1, mBounds); 
     c.drawText(mFirstChar, 0, 1, 0 + width/2, 0 + height/2 
       + (mBounds.bottom - mBounds.top)/2, mPaint); 
    } else { 
     c.drawBitmap(mDefaultBitmap, 0, 0, null); 
    } 
    return bitmap; 
} 
관련 문제