在android 4.4.3上面,联系人的头像默认显示首字母,但是不支持中文字符,如下图:

如果联系人名字的第一位是英文字符(a-z || A-Z),则默认头像将显示该首字母。

如果支持中文时显示第一个汉字,那就happy了。

那就看看如何通过修改源代码来实现这一小功能吧~

我们还是先了解下联系人头像加载的流程吧~

联系人头像加载这个问题还是很有意思的,在Contacts中使用ContactPhotoManager类(严格来讲是这个类的子类)来实现头像的异步加载。

这个类还使用了LruCache来缓存图片,相当的强大,对图像的异步加载和缓存有兴趣的同志们可以看看。

以主页面的联系人列表加载头像为例。大致的调用流程为(只针对没有设置头像的联系人,即photoUri是null):

DefaultContactListAdapter->bindView()
  ContactEntryListAdapter->buildQuickContact()
    ContactEntryListAdapter->getDefaultImageRequestFromCursor()
      ContactPhotoManagerImpl->loadPhoto()->provider:LetterTileDefaultImageProvider // 注意,使用的是DEFAULT_AVATAR对象
        LetterTileDefaultImageProvider->applyDefaultImage()
          LetterTileDefaultImageProvider->getDefaultImageForContact()
            LetterTileDrawable->drawLetterTile()->firsr char:高

在drawLetterTile函数执行drawText之前会调用isEnglishLetter来判断字符串的首字符是否为英文字符,如果是,则将首字母画上去;

否则,使用默认头像

    private static boolean isEnglishLetter(final char c) {return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z');}

通过上面的流程解析,我们可以确定,是isEnglishLetter函数导致在中文字符不被描画。

嗯,那我们就改造一下这个函数吧。不废话,直接上代码~

    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));}

至于isChinese函数的实现,代码就不贴了,有兴趣的可以参考我的一篇判断字符为中文、日文、韩文的文章(http://www.cnblogs.com/Lefter/p/3804051.html)

经过这个改造后,我们就可以让默认头像显示中文名字的第一个汉字了!

具体修改如下。严重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;  
    } 
    
   //具体路径 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 is an english letter
        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 in 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);
        }
    
     }
   
          //为什么头像的背景会有8种颜色   
   <!-- 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;  //八种颜色随机生成
    
    //获取颜色
    private int pickColor(final String identifier) {
        if (TextUtils.isEmpty(identifier) || mContactType == TYPE_VOICEMAIL) {
            return sDefaultColor;
        }
        // String.hashCode() implementation is not supposed to change across java versions, so
        // this should guarantee the same email address always maps to the same color.
        // The email should already have been normalized by the ContactRequest.
          //随机取得颜色值
        final int color = Math.abs(identifier.hashCode()) % NUM_OF_TILE_COLORS;
        return sColors.getColor(color, sDefaultColor);
    }

android 4.4.3上面,联系人的头像默认显示首字母,但是不支持中文字符,修改支持中文相关推荐

  1. Android联系人、ListView实现姓名首字母分类和字母定位查找

    目    录(本篇字数:2504) 案例 源码下载 思路及实现 一.左侧字母检索器 二.列表显示字母分类 三.列表适配器的逻辑代码 四.汉字转拼音的一个工具类 案例 今天,我们来实现这样的一个小Dem ...

  2. Android 关于TextView 默认显示英文字母大写问题

    开发问题记录了一下,TextView小写 字母总是显示为大写的问题通过查阅资料 解决方法: 在xml中设置 android:textAllCaps="false"即可

  3. vue用户没有头像用姓名首字母做头像

    avatar.js /** *@param widths 画布宽 *@param heights 画布高 *@param fontSize 字体大小 *@param id canvas id值 *@p ...

  4. vue中根据用户昵称首字母生成头像和颜色

    需求:项目中需要做一个粗糙的评论板块,用户评论时需要显示头像,但是不需要去更换改头像 思路:用户昵称首字母作为头像,并且根据用户首字母生成固定的颜色,否则每次颜色都会随机 例如: 方法一 1.安装头像 ...

  5. 组件用.vue还是.js_一个Vue.js 2.0组件,用于生成首字母缩写或基于图像的头像

    组件用.vue还是.js Vue头像组件 (vue-avatar-component) This vue.js component provide a simple way to generate r ...

  6. android contacts电话查询头像,android透过查询电话号码获取联系人头像

    android通过查询电话号码获取联系人头像 // 取得Intent中的頭像 ivShowImage = (ImageView) findViewById(R.id.call_log_detail_c ...

  7. android 添加通讯录联系人头像,Android 手机通讯录开发时给联系人添加头像失败的坑...

    Android 手机通讯录开发时给联系人添加头像失败的坑,在给联系人添加头像代码 Bitmap photo = ...; // 将 Bitmap 转为 byte[] byte[] bytes = Ls ...

  8. android的contentResolver,contentProvider简介(附带个获取手机联系人及头像实例)

    介绍 android中有个ContentProvider(内容提供者)还有个ContentResolver(内容解析者) 简单来说,contentProvider就是将自己app的数据库共享,使得其他 ...

  9. Android使用READ_CONTACTS读取手机联系人

    实例代码: package com.example.readcontacts;import java.io.InputStream; import java.util.ArrayList;import ...

最新文章

  1. 自学python清单-python学习清单
  2. Makefile 书写命令
  3. 蓝马linux命令连另一台电脑,配置使用别的电脑连接另一台电脑当中的虚拟机项目...
  4. k8s minikube管理镜像相关命令:minikube image list/pull/load
  5. c语言一个一个读取文件字节,C语言中二进制文件的读取
  6. 计算机专业多元协同,项目主导多元协同资源开放—软件技术专业人才培养体系的创新实践.pdf...
  7. AOP就是面向切面编程,我们可以从几个层面来实现AOP。 ![](https://upload-im
  8. Linux内存管理(一)——从硬件角度看内存管理
  9. HardSoft-Viewer PHP_index.php
  10. python - bs4提取XML/HTML中某个标签下的属性
  11. python中string库_Python——string库
  12. 六级(2020/12-2) Section B
  13. python实用脚本(三)—— 通过有道智云API实现翻译
  14. android appwidget桌面插件,Android:AppWidget、桌面小部件
  15. iOS 防止录屏和截屏的监听
  16. DirectShow资料
  17. UVa 12325 - Zombie's Treasure Chest(暴力枚举+预处理)
  18. 认认真真推荐10个优秀的公众号
  19. Qt事例: QScrollArea滚动区域
  20. 来看看中美互联网差异

热门文章

  1. java birt project_Eclipse BIRT问题解决汇总(不断更新)
  2. 计算机英语四级证书编号查询,英语四级99宿舍网查准考证号
  3. Genelec G Three有源音箱评测
  4. 数据分析项目-英国礼品商城数据分析
  5. iperf 测试极限带宽
  6. 自己感觉写的一个比较经典的报表sql
  7. Android monkey 基础入门介绍
  8. Android Studio for Mac黑色皮肤设置
  9. 69张一刻相册日漫绘画分享
  10. start.S:88: Error: invalid constant (61f) after fixup