文档章节

Android应用字体替换

猴亮屏
 猴亮屏
发布于 2017/04/27 18:08
字数 966
阅读 67
收藏 0

很多应用程序都有替换字体的需求,主要是设计可能要显示一个独特的字体,比如有多少人,花费了多少钱,这种用不同的字体显示会有强提醒的作用,增强应用程序的体验。

替换字体又一般分为部分替换,比如只正对一行显示中的某一段或者某一个数字进行替换,

我们知道系统中我们可以对字体显示View设置Android:typeface属性,一般都有以下几种值可以选择:在手机上四中typeface替换,展示效果差距不大。

monospace 
sanf 
serif 
normal

那如何才能自己用自定义的字体库来进行替换呐?

局部替换

一般都采用以下方法:针对要显示的TextView设置不同的Typeface,我们可以将一个ttf字库构造成一个Typeface,将构造的Typeface设置到要显示的TextView。这种比较方便的是字体库比较小,如果明确知道要显示的字库是什么,我们就可以只针对该字库来进行ttf生成。可以在一些开源的平台进行ttf的生成。ttf生成链接 样例代码如下

private static Typeface typeface;

TextView tv = new TextView(this);
tv.setTypeface(getTypeface(context));

public static Typeface getTypeface(Context context){
   if (typeface == null) {
   typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto_Light.ttf");
        }
    return typeface;
    }

只要对TextView设置setTypeface就可以了。

上面说到了局部的替换,如果全局需要替换又要怎么办。全局替换一般会采用以下几种方法,

全局替换

1: 遍历所有的view,在页面加载的时候进行全局设置Typeface,比如我们只针对TextView进行设置:

public void setTypeface(ViewGroup root, Typeface typeface){
    if(root==null || typeface==null){
        return;
    }
    int count = root.getChildCount();
    for(int i=0;i<count;++i){
        View view = root.getChildAt(i);
        if(View instanceof TextView){
            ((TextView)view).setTypeface(typeface);
        }else if(View instanceof ViewGroup){
            setTypeface((ViewGroup)view, typeface);
        }
    }
}

2:想当然认为只要替换掉系统默认的Typeface是否就可以生效那,我们采用反射替换掉系统默认的Typeface。替换时机为Application加载的时候,可以在Application的onCreate中进行替换。

public final class AppTypeface {

    private enum DefaultFont {
        DEFAULT("DEFAULT"),
        DEFAULT_BOLD("DEFAULT_BOLD"),
        MONOSPACE("MONOSPACE"),
        SERIF("SERIF"),
        SANS_SERIF("SANS_SERIF");

        private String value;

        DefaultFont(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }
    }

    public static boolean replace = false;

    public static final String REPLACE_FONT = "fonts/Roboto_Light.ttf";

    /**
     * @param context
     */
    public static final void init(Context context) {
        if (replace) {
            final Typeface replace = Typeface.createFromAsset(context.getAssets(), REPLACE_FONT);
            for (DefaultFont defaultFont : DefaultFont.values()) {
                replaceFont(defaultFont.getValue(), replace);
            }
        }
    }

    public static final void replaceFont(String fontName, Typeface typeface) {
        try {
            final Field staticField = Typeface.class.getDeclaredField(fontName);
            staticField.setAccessible(true);
            staticField.set(null, typeface);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

}

但是最终验证效果为,只单单是代码层面的替换,是没有效果的,在网上搜寻方案是发现代码替换与theme主题结合是能够生效的。theme设置如下:

    <style name="LightBaseTheme" parent="Theme.AppCompat.Light">
        <item name="android:typeface">monospace</item>
    </style>

但是全局替换会面临如下的问题: 
1:字体库的生成,如果是英文应用,ASCII表就基本就包括了所有需要替换的字符,但是中文应用,大家都知道的是,中文字符一共有10万多个,就算最常用的也有好几千,我在阿里妈妈webfont上试着生成一个包含常用字体的ttf,发现该平台最多支持7500多个字,再多就不能生成,这样会导致应用恰好包含了未替换的字体,展示效果很差。 
2:如果不考虑ttf字体库的大小,搜索下来发现一般一个ttf就有10M,这样的大小对应用来说安装包增长太大,可以预见的是,包越大用户安装的意愿就越小。 
3:上面的方法虽然在我手头的机器都是有效果的,但是不保证所有的机器都有效果。可能会出现加载错误或者渲染错误。

本文转载自:http://blog.csdn.net/xueshanhaizi/article/details/50838066

共有 人打赏支持
猴亮屏

猴亮屏

粉丝 35
博文 525
码字总数 57346
作品 4
北京
Android工程师
私信 提问
替换整个APP字体--修改全局字体样式

原文地址 首先将项目需要的字体资源放置在app下: 注意,字体ttf文件只能用英文字母,中文会报找不到文件异常。 未设置之前的布局样式: 字体文件准备好后,我们就可以按需设置自己想要的字体...

王先森oO
09/14
0
0
1.Android系统源代码目录与系统目录

1.Android源代码的目录中包含了Android系统所有的源代码,从底层驱动到上层应用,Android系统对所有文件都进行了详细管理; 2.而在手机中,Android系统的目录与源代码的目录并不是一一对应的...

凌川江雪
07/28
0
0
apkplug主题皮肤切换之通用主题-04

该文章基于V1.6.9版本 apkplug主题切换有两个层次的切换,这篇文章只讲解通用主题切换层次 一 何为通用主题切换 apkplug通用主题切换可以简单的理解为一套可动态替换的系统主题(由主题包提供...

梁大帅
2014/05/26
0
0
SpannableString与SpannableStringBuilder

一、概述 1、SpannableString、SpannableStringBuilder与String的关系 首先SpannableString、SpannableStringBuilder基本上与String差不多,也是用来存储字符串,但它们俩的特殊就在于有一个...

菜南瓜
2015/05/18
0
0
Android 打造自己的个性化应用(一):应用程序换肤主流方式的分析与概述

Android平台api没有特意为换肤提供一套简便的机制,这可能是外国的软件更注重功能和易用,不流行换肤。系统不提供直接支持,只能自行研究。 换肤,可以认为是动态替换资源(文字、颜色、字体...

长平狐
2012/09/03
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

tomcat编译超过64k大小的jsp文件报错原因

  今天遇到一个问题,首先是在tomcat中间件上跑的web项目,一个jsp文件,因为代码行数实在是太多了,更新了几个版本之后编译报错了,页面打开都是报500的错误,500的报错,知道http协议返回...

SEOwhywhy
20分钟前
0
0
flutter http 请求客户端

1、pubspec文件管理Flutter应用程序的assets(资源,如图片、package等)。 在pubspec.yaml中,通过网址“https://pub.dartlang.org/packages/http#-installing-tab-”确认版本号后,将http(0...

渣渣曦
20分钟前
0
0
Django基本命令及moduls举例

一、Django基本命令 1.创建项目 django-admin.py startproject mysite 创建后的项目结构:- mysite - mysite #对整个程序进行配置 - init #导入包专用- settings ...

枫叶云
35分钟前
6
0
zabbix安装

rpm -ivh http://repo.webtatic.com/yum/el6/latest.rpm 安装jdk rpm -ivh (自行在网上下载rpm包) 安装php并修改相应参数 yum -y install php56w php56w-gd php56w-mysqlnd php56w-bcmath......

muoushi
36分钟前
4
0
MySQL自增属性auto_increment_increment和auto_increment_offset

MySQL的系统变量或会话变量auto_increment_increment(自增步长)和auto_increment_offset(自增偏移量)控制着数据表的自增列ID。 mysql> show tables;Empty set (0.00 sec)mysql> CREATE TA......

野雪球
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部