On Android 4.4.3 , the contact's avatar displays the first letter by default, but does not support Chinese characters such as:
If the first digit of the contact's name is an English character (A-Z | | A-Z), the default avatar will display the first letter.
If the first Chinese character is displayed when Chinese is supported, it will be happy.
Then let's see how to do this by modifying the source code to achieve this small function ~
Let's get to know the process of the contact avatar loading first.
Contact Avatar Loading This problem is still interesting, in contacts use the Contactphotomanager class (strictly speaking subclass of this class) to achieve the asynchronous loading of the avatar.
This class also uses LRUCache to cache images, quite powerful, and interested in the asynchronous loading and caching of images that comrades can look at.
Use the contact list on the main page to load the avatar as an example. The approximate calling process is (only for contacts that do not have an avatar set, that is, Photouri is null):
Defaultcontactlistadapter->bindview ()
Contactentrylistadapter->buildquickcontact ()
Contactentrylistadapter->getdefaultimagerequestfromcursor ()
Contactphotomanagerimpl->loadphoto ()->provider:LettertiledefaultimageproviderNote that the Default_avatar object is used
Lettertiledefaultimageprovider->applydefaultimage ()
Lettertiledefaultimageprovider->getdefaultimageforcontact ()
Lettertiledrawable->Drawlettertile ()->FIRSR Char: High
Before the Drawlettertile function executes DrawText, it calls Isenglishletter to determine if the first character of the string is an English character, and if so, the first letter is drawn up;
Otherwise, use the default avatar
private static Boolean isenglishletter (final char c) { return
(' A ' <= c && c <= ' Z ') | | (' A ' <= C && c <= ' z ')
By parsing the above process, we can determine that the Isenglishletter function causes the Chinese characters not to be depicted.
Well, let's just change the function. No nonsense, directly on the code ~
private static Boolean isenglishletter (final char c) { return
(' A ' <= c && c <= ' Z ') | | (' A ' <= C && c <= ' z ') | | Ischineseletter (c); }
private static Boolean ischineseletter (final char c) { return
Ischinese (string.valueof (c)); }
As for the implementation of the Ischinese function, the code is not affixed, interested can refer to one of my judgment characters for Chinese, Japanese, Korean article (http://www.cnblogs.com/Lefter/p/3804051.html)
After this transformation, we can let the default avatar display Chinese name of the first Chinese character!
The specific changes are as follows. Critical OK
private static Boolean Isenglishletter (final char c) {
Return (' A ' <= c && c <= ' Z ') | | (' A ' <= C && c <= ' z ');
}
private static Boolean Ischineseletter (final char c) {
return Ischinese (c);
}
private static Boolean Ischinese (char c) {
Character.unicodeblock UB = Character.UnicodeBlock.of (c);
if (UB = = Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| UB = = Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|| UB = = Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
|| UB = = Character.UnicodeBlock.GENERAL_PUNCTUATION
|| UB = = Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|| UB = = Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
return true;
}
return false;
}
Specific path com.android.contacts.common.lettertiles; Lettertiledrawable.java
private void Drawlettertile (final canvas canvas) {
Draw background color.
Spaint.setcolor (Pickcolor (midentifier));
Spaint.setalpha (Mpaint.getalpha ());
Canvas.drawrect (GetBounds (), spaint);
Draw Letter/digit only if the first character are an 中文版
if (mdisplayname! = null && (isenglishletter (Mdisplayname.charat (0)) | | ischineseletter (MDISPLAYNAME.CHARAT (0 )))) {
Draw Letter or digit.
Sfirstchar[0] = character.touppercase (Mdisplayname.charat (0));
Scale text by canvas bounds and user selected scaling factor
Final int mindimension = Math.min (GetBounds (). Width (), getbounds (). height ());
Spaint.settextsize (Mscale * slettertotileratio * mindimension);
Spaint.settextsize (stileletterfontsize);
Spaint.gettextbounds (Sfirstchar, 0, 1, srect);
Spaint.setcolor (Stilefontcolor);
Final Rect bounds = getbounds ();
Draw the letter on the canvas, vertically shifted up or down by the user-defined
Offset
Canvas.drawtext (Sfirstchar, 0, 1, Bounds.centerx (),
Bounds.centery () + Moffset * bounds.height () + srect.height ()/2,
Spaint);
}else {
Draw The default image if there is no letter/digit to be drawn
Final Bitmap Bitmap = Getbitmapforcontacttype (Mcontacttype);
Drawbitmap (Bitmap, Bitmap.getwidth (), Bitmap.getheight (),
Canvas);
}
}
Why there are 8 colors in the background of the Avatar
<!--Make sure to also update lettertileprovider#num_of_tile_colors when adding or removing
Colors--
<array name= "Letter_tile_colors" >
<item> #33b679 </item>
<item> #536173 </item>
<item> #855e86 </item>
<item> #df5948 </item>
<item> #aeb857 </item>
<item> #547bca </item>
<item> #ae6b23 </item>
<item> #e5ae4f </item>
</array>
/** This should match the total number of colors defined in Colors.xml for Letter_tile_color */
private static final int num_of_tile_colors = 8; Random generation of Eight colors
Get color
private int Pickcolor (final String identifier) {
if (Textutils.isempty (identifier) | | mcontacttype = = type_voicemail) {
return sdefaultcolor;
}
String.hashcode () Implementation is isn't supposed to change across Java versions, so
This should guarantee the same e-mail address always maps to the same color.
The email should already has been normalized by the contactrequest.
Randomly get color values
final int color = Math.Abs (Identifier.hashcode ())% Num_of_tile_colors;
return Scolors.getcolor (color, sdefaultcolor);
}
Android 4.4.3 above, the contact's avatar display the first letter by default, but does not support Chinese characters, modify the support English