5

Android应用使用自定义字体的一些探究

 3 years ago
source link: http://www.androidchina.net/3305.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

最近团队里面在做程序界面统一的工作,因此希望统一字体,接到一个研究怎么自定义字体的任务。因为我们的开发模式,所以需要研究在界面内的字体自定义,以及webview的显示中的字体自定义。

android系统内置字体

android 系统本身内置了一些字体,可以在程序中使用,并且支持在xml配置textView的时候进行修改字体的样式。支持字段为android:textStyle ,android:typefaceandroid:fontFamily,系统内置了normal|bold|italic三种style, 内置了normalsans,serif,monospace,几种字体(实测这几种字体仅英文有效),typace和fontFamily功能一样。

使用自定义的字体

以上的方式可以改变字体的样式,还不是真正的自定义。

android系统支持TypeFace,即ttf的字体文件。

我们可以在程序中放入ttf字体文件,在程序中使用Typeface设置字体。

第一步,在assets目录下新建fonts目录,把ttf字体文件放到这。
第二步,程序中调用:

AssetManager mgr=getAssets();//得到AssetManager
Typeface tf=Typeface.createFromAsset(mgr, "fonts/ttf.ttf");//根据路径得到Typeface
tv.setTypeface(tf);//设置字体

注意ttf文件命名不能使用中文,否则可能无法加载。

对于需要使用比较多的地方,可以写一个TextView的子类来统一处理。

在webview中使用自定义地体

对于本地的网页,在asset目录放字体文件,并在css中添加以下内容,自定义一个字体face,并且在需要的地方使用这个字体face即可。

@font-face {
font-family: "MyFont";
}
h3 { font-family:"MyFont"}

对于在线的网页,则需要把字体文件放到服务器,使用同样的方式定义字体face,应用到每个地方。

为了减少网页或者说服务器端的工作,可以使用本地注入的方式注入font-face的css,并对整个网页进行样式替换。

给webview自定义webViewClient,重写onPageFinish,在其中添加如下内容:

view.loadUrl("javascript:!function(){" + "s=document.createElement('style');s.innerHTML=" + "\"@font-face{font-family:myhyqh;src:url('**injection**/hyqh.ttf');}*{font-family:myhyqh !important;}\";" + "document.getElementsByTagName('head')[0].appendChild(s);" + "document.getElementsByTagName('body')[0].style.fontFamily = \"myhyqh\";}()");

由于网页上是没有权限访问本地的asset文件夹的,因此我们需要拦截请求来加载本地的文件,我这里替换了file:///android_assets/**injection**/了,我们还需要重写
shouldInterceptRequest
在请求为我们这个字体文件的时候,加载本地文件:

@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
WebResourceResponse response = super.shouldInterceptRequest(view, url);
CLog.i("load intercept request:" + url);
if (url != null && url.contains("**injection**/")) {
//String assertPath = url.replace("**injection**/", "");
String assertPath = url.substring(url.indexOf("**injection**/") + "**injection**/".length(), url.length());
try {
response = new WebResourceResponse("application/x-font-ttf", "UTF8", getAssets().open(assertPath));
} catch (IOException e) {
e.printStackTrace();
}
}
return response;
}

使用字体统一界面,但是也遇到了一些问题,如下:

  1. 运行速度变慢(毫秒级,用户觉查不到),由于需要读取自定义的字体文件,以及需要渲染,比使用系统字体要慢。
  2. emoji在5.0以下的系统会有问题。
  3. 在网页,如果采用服务器文件的方法,会消耗用户的流量
  4. 在网页,采用本地注入方式,因为是在onpagefinish后才开始加载字体,因此页面会重新渲染,影响效果。这样还会造成网页可能会出现样式错误。

因为我们的程序中大量使用到emoji,以及考虑到性能的问题,决定还是使用系统自带的字体了。

如果你在这方面有更好的方案,欢迎交流!

原文地址:http://blog.isming.me/2015/07/07/android-custom-font/,转载请注明出处。

转载请注明:Android开发中文站 » Android应用使用自定义字体的一些探究


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK