Android上显示生僻字的方法
安卓5.0+是可以显示所有(8万多个)Unicode汉字的,本文介绍显示生僻汉字的方法,这个方法也适用于其它特殊字符。
Unicode值在0xFFFF以下的(2万多个简体、繁体)汉字早已被广泛支持,所以本文不把它们看作生僻字。
本文说的生僻字是指Unicode值在0xFFFF以上的汉字,这个范围也叫non-BMP。
可以看这篇文章了解汉字的大致分布。
主要有4个关键点:
一、需使用Android 5.0以上系统。
经过我的测试,在Android 4.3.1模拟器、4.4.2模拟器上会出现问题,而在Android 5.0.2模拟器、6.0真机、7.0模拟器上正常。
问题见本文最后部分的两张截图:附1、附2。
二、确保字符集能覆盖生僻字。
也就是在文件、数据库保存字符串时使用的字符集,应该是:GB18030、UTF-8、UTF-16、UTF-32等能支持所有Unicode字符的字符集。
注意a:不要使用GB2312、GBK或BIG5字符集,它们的范围有限,都不支持生僻字(Unicode值大于0xFFFF)。
注意b:不要在Android程序的配置xml文件里写生僻字,Android在用UTF-8解码这些xml时,支持的范围并不完整。这个bug在Android 6.0里被修复。见此帖。
按如下方法把字符串读入String后,我们进入下一个关键点。
byte[] b = read_bytes_from_somewhere();
String str = new String(b, "GB18030");
三、String在处理生僻字时会使用surrogate对。
Java的String使用的是UTF-16编码。String的一个char占两个字节,能表示0~0xFFFF之间的数值范围。
于是,根据UTF-16的规则,在String里:常用字符(Unicode值小于等于0xFFFF)用一个char表示;剩下的字符(Unicode值大于0xFFFF)用两个char组合表示,这两个char叫surrogate对儿。所以我们的生僻字符须要用两个char组合表示。
surrogate对的原理是:两个char各有一个保留区域,这个保留区域有1,024个位置,于是1,024x1,024等于1,048,576,再加上单个char包含的字符,正好能覆盖Unicode所有的1,114,112个位置点。
在这里,搞清楚两个概念就可以了:
- char,一个char就是一个两字节整数。它是String的最小单位,一个String包含0个或若干个char。String对象的length()函数返回的就是char的个数。
- code point,一个code point就是一个Unicode字符,一个实际的字符。在String里,它可能用1个char表示,也可能用2个char组合表示,没有第三种可能。
所以,在处理生僻字时,String的length()函数的返回值可能大于实际字符数,想知道String的实际字符数可以用codePointCount()函数。同理,charAt()等基于char操作的函数可能也不再适用。
四、使用支持生僻字的字体。
就算程序内在支持生僻字,字体不支持也显示不出来。包括默认字体在内的很多字体都不支持生僻字。
我们可以找一个支持生僻字的字体,然后放到程序的资源目录里,指定程序使用它而不是系统的默认字体。
然后按以下方法使用该字体就可以了(出处):
//得到TextView控件对象
TextView textView = (TextView) findViewById(R.id.custom); //将字体文件保存在assets/fonts/目录下,创建Typeface对象
Typeface typeFace = Typeface.createFromAsset(getAssets(), "fonts/KaiXinSong.ttf"); //使用字体
textView.setTypeface(typeFace);
注意a:打包了字体的程序会大很多,这也是没有办法的事。除非做成按需下载字体,这就依赖网络了;或者生成一个只包含所需汉字的字体文件。(2017年发布的Android Support Library v26增强了对字体的支持,见此视频。)
注意b:各字体可能会有自己的侧重点,比如支持生僻汉字的字体可能不支持emoji,支持emoji的字体可能不支持生僻汉字。
注意c:可以用SpannableString为一个字符串的部分字符使用指定的字体,见为部分字符指定字体、在SpannableString使用指定字体。
在按如上方法使用了开心宋体后,已经可以在Android 5.0.2模拟器上显示各区汉字:
在Android 5.0.2模拟器上默认字体的效果,可以看到CJK统一汉字扩展B、C、D、E区的汉字都无法显示:
附1,在Android 4.4.2模拟器上,使用开心宋体后,常用字反倒显示不出来了。
在4.3.1、4.4.2上,使用Simsun-ExtB字体也有类似情况,所以这应该是安卓4.x的问题。
难道是系统不支持多于65536个字符的字体?我没有去验证,仅仅是猜测。
附2,在Android 4.4.2模拟器上,使用默认字体的效果:
Android上显示生僻字的方法的更多相关文章
- 关于Unity程序在IOS和Android上显示内嵌网页的方式
近期因为有须要在Unity程序执行在ios或android手机上显示内嵌网页.所以遍从网上搜集了一下相关的资料.整理例如以下: UnityWebCore 从搜索中先看到了这个.下载下来了以后发现这个的 ...
- JS文件中的中文在网页上显示为乱码解决方法
转自:http://www.pc6.com/infoview/Article_63835.html 如果JS文件中的中文在网页上显示为乱码,不妨采用本文章中的方法来试一试,或许能解决使你很头疼的问题. ...
- HTML让文字在图片上显示的几种方法
第一种方式是image 作为背景图片,即:background:url("......."); 第二种方式是将img块与文字块(文字块采用span标签显示)放在同一个div 中,然 ...
- 日期在苹果手机上显示NaN的处理方法
注意两点即可: 1.苹果只认识 yyyy/mmmm/dddd/ 这类格式的日期 2.如果输出后还要进行处理日期对比,苹果默认会带中文字,如:年月日,需要转成上面1当中的日期格式在转时间戳进行比较 G ...
- 在远程X server上显示图形的设置方法
1.在服务器的/etc/ssh/sshd_config中,设置X11Forwarding yes,然后重启ssh服务,cd /etc/init.d这个目录下执行 ./ssh restart 2.在客户 ...
- unity,将camera设为don't clear在android上会显示不正常
将camera设置为don't clear,在pc和ios上显示没问题,但在android上显示不正常,改为only depth可以.
- 教你用PS制作雨天窗户上透明水滴字
雨天窗户上透明水滴字制作方法很简单,主要利用图层样式来实现.学习后可以让你对图层样式有更好的了解,认识. 先看下完成后的效果图: 步骤1: 在Photoshop中我们新建或Ctrl+N,创建1920x ...
- 利用SQLite在android上实现增删改查
利用SQLite在android上实现增删改查 方法: 一.直接利用database.execSQL()方法输入完整sql语句进行操作 这种方法适用于复杂的sql语句,比如多表查询等等 这里适合于增删 ...
- Android上的MVP:如何组织显示层的内容
MVP(Model View Presenter)模式是著名的MVC(Model View Controller)模式的一个演化版本,目前它在Android应用开发中越来越重要了,大家也都在讨论关于M ...
随机推荐
- 【C++】关键字inline
1. 引入inline关键字的原因 在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数. 栈空间就是指放置程序的局部数据(也就是 ...
- 获取邮箱使用情况、以及最后一次logon时间
# 每天收发邮件数 # https://gallery.technet.microsoft.com/scriptcenter/Count-sent-and-recceived-f9c66cf7 # 获 ...
- c#委托之浅析
前言: 这章我们将弄懂,委托是什么?有什么作用?在什么样的场景下可以启到什么作用? 委托适用的场景:当确定处理一个任务时,不确定其处理任务的方法时可使用,这样可以提高扩展性,调用符合条件的处理方法,避 ...
- MongoDB中的读写锁
1. MongoDB 使用的锁 MongoDB 使用的是“readers-writer”锁, 可以支持并发但有很大的局限性当一个读锁存在,许多读操作可以使用这把锁,然而, 当一个写锁的存在,一个单一的 ...
- Json序列化自定义属性名称
using Newtonsoft.Json; [JsonProperty("userName")] public string UserName { get; set; }
- springboot连mysql报一个奇怪的错误
错误提示:Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection ...
- MySQL5.7.17解压版安装
首先将mysql解压,公司的mysql解压后自带my.ini文件,结构如下: 在my.ini文件中配置的data路径在my文件夹下,需要删掉,然后修改my.ini文件中basedir和datadir路 ...
- Spring boot 的 properties 属性值配置 application.properties 与 自定义properties
配置属性值application.properties 文件直接配置: com.ieen.super.name="MDD" 自定义properties文件配置:src/main/r ...
- substr函数学习
今天写了单词接龙这道恶心题,在想有没有函数能直接去返回string类型一个区间的字符串,没想到还真有,那就是sudstr 坑点 感觉这个函数有点逗比-- 别的都是str在前,这个偏要在后-- 也许是我 ...
- Sublime Text 3安装Package Control
Package Control官网:https://packagecontrol.io/installation#st3 ctrl + ` 或者 View > Show Console呼出控制台 ...