我想知道它们是如何生成的,以及每次打开应用程序或存储(缓存)时是否生成它们。
它只是一个画布(以编程方式)或者他们使用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>
答案 0 :(得分:46)
每次打开应用程序或存储(缓存)时都会生成
小栏A,小栏B.有一个小的缓存使用,但它不是你想的。每个图块可以分成4个部分,缓存用于检索特定位置。就背景而言,使用String.hashCode
映射颜色以确保相同的电子邮件地址(或密钥)始终映射到相同的颜色。但实际的字母是使用Canvas.drawText
绘制的。
以下是一个例子:
/**
* 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();
}
}
}
以下是默认颜色和文字大小:
<!-- 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>
<强>实施强>
@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));
}
“T”,“E”,“S”,“T”的结果:
答案 1 :(得分:1)
建立@ adneal的响应,如果我们想生成循环图标,我们可以修改getLetterTile函数,如下所示:
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;
}