文档章节

Android应用字体替换

猴亮屏
 猴亮屏
发布于 2017/04/27 18:08
字数 966
阅读 63
收藏 0
点赞 0
评论 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

共有 人打赏支持
猴亮屏

猴亮屏

粉丝 29
博文 503
码字总数 52840
作品 2
北京
Android工程师
Android项目实战(一): SpannableString与SpannableStringBuilder(转)

前言: 曾经在一些APP中的一些类似“帮助”“关于”的界面看过一行文字显示不同的颜色的效果,如下效果: 本软件是一款高、大、上的社区类软件。 一般来说,这应该是由一个TextView来显示的,...

听着music睡 ⋅ 2014/11/13 ⋅ 0

Android插件化原理(一)Activity插件化

相关文章 Android深入四大组件系列 Android解析AMS系列 Android解析ClassLoader系列 前言 四大组件的插件化是插件化技术的核心知识点,而Activity插件化更是重中之重,Activity插件化主要有三...

刘望舒 ⋅ 05/29 ⋅ 0

Android初级第九讲之适配和调试

本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! Android适配需要考虑方方面面,主要是图片字体大小和API,但也要考虑其他场景下的一些问题。 先熟悉一下Android设备的dpi...

liuzxgeek ⋅ 2016/12/14 ⋅ 0

Android 浅谈 maxEms 属性

小菜最近调整一个小需求,为了整体显示效果,需要限制一部分文字的长度,超过部分以...代替。 小菜本想偷个懒,用 android:maxLength="6" 属性配合 android:maxLines="1" 以及 android:elli...

阿策神奇 ⋅ 05/12 ⋅ 0

Android HWUI硬件加速模块浅析

原址 什么是硬件加速(What) 传统软件的UI绘制是依靠CPU来完成的,硬件加速就是将绘制任务交由GPU来执行。Android系统负责硬件加速的模块主要是HWUI,如下图所示: 为什么要硬件加速(Why)...

u010164190 ⋅ 04/27 ⋅ 0

新建cordova应用,插件开发教程系列(总目录)

以下几篇是连续的教程,代码也是连续的,包括如下章节: 新建cordova应用 https://my.oschina.net/u/1251858/blog/1799002 使用cordova把h5应用打包成apk https://my.oschina.net/u/1251858/...

canneljls ⋅ 04/21 ⋅ 0

Gradle实现Android多渠道定制化打包

最近在项目中遇到需要实现 Apk 多渠道、定制化打包, Google 、百度查找了一些资料,成功实现了上述功能,在此记录以备不时之需,温故而知新,可以为师矣~ 需求可以总结如下: 如何实现多个 ...

玄学酱 ⋅ 2017/08/03 ⋅ 0

Android谷歌官方的自适应TextView字体大小的解决方案

Android谷歌官方的自适应TextView字体大小的解决方案 有时候UI限定了TextView宽度或者布局的控件空间尺寸不足,而此时的TextView里面的文本就无法完全正常显示。自适应TextView文本大小字体以...

zhangphil ⋅ 04/14 ⋅ 0

Android开源框架源码鉴赏:VirtualAPK

关于作者 郭孝星,程序员,吉他手,主要从事Android平台基础架构方面的工作,欢迎交流技术方面的问题,可以去我的Github提issue或者发邮件至guoxiaoxingse@163.com与我交流。 文章目录 一 Vi...

郭孝星 ⋅ 02/10 ⋅ 0

探索Activity启动流程-实现打开插件中的Activity

通过分析Activity的启动流程,探索Android的插件化,下面通过源码分析实现一个简单的插件化 打开一个 未安装apk中的Activity 开始分析 Activity的启动流程从 startActivity开始 然后通过 In...

liwg ⋅ 05/11 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

开启Swarm集群以及可视化管理

在搭建的两台coreos服务器上开启swarm集群 前置条件: docker均开启2375端口 同一个局域网内 主服务器上安装Portainer容器 安装Portainer容器执行: docker run -d -p 9000:9000 --restart=a...

ykbj ⋅ 20分钟前 ⋅ 0

单例设计模式

1、单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例 2、饿汉式单例类 在这个类被加载时,静态变量instance会被初始化,此时类的私有构造子会被调用 饿汉式是典型...

职业搬砖20年 ⋅ 25分钟前 ⋅ 0

前端基础(四):前端国际规范收集

字数:1142 阅读时间:5分钟 前言 由于前端技术的灵活性和杂乱性,导致网上的许多解决方案不够全面甚至是完全错误,容易起到误导作用。所以,我对搜索到的解决方案往往是存疑态度。那么,如何...

老司机带你撸代码 ⋅ 27分钟前 ⋅ 0

Failed to open/create Network-VirtualBox Host-Only

虚拟机版本 : Oracle Vm VirtualBox 5.2.12 报错时机:开网卡二,重启虚拟机报错 "Failed to open/create the internal network 'HostInterfaceNetworking-VirtualBox Host-Only Ethernet Ada......

p至尊宝 ⋅ 30分钟前 ⋅ 0

三分钟学会如何在函数计算中使用 puppeteer

摘要: 使用 puppeteer 结合函数计算,可以快速的构建弹性的服务完成各种功能,包括:生成网页截图或者 PDF、高级爬虫,可以爬取大量异步渲染内容的网页、模拟键盘输入、表单自动提交、登录网...

阿里云云栖社区 ⋅ 33分钟前 ⋅ 0

springMVC接收表单时 Bean对象有Double Int Char类型的处理

前台ajax提交表单price为double类型 后台controller就介绍不到 400错误 前台 实体类: public class ReleaseMapIconConfig{ private String id; private long maxValue; private long minVal......

废柴 ⋅ 36分钟前 ⋅ 0

ZOOKEEPER安装

工作需要在ubuntu上配置了一个zookeeper集群,有些问题记录下来。 1. zookeeper以来java,所以首先要安装java。但是ubuntu系统有自带的jdk,需要通过命令切换java版本: $ sudo update-alter...

恰东 ⋅ 39分钟前 ⋅ 0

linux 进程地址空间的一步步探究

我们知道,在32位机器上linux操作系统中的进程的地址空间大小是4G,其中0-3G是用户空间,3G-4G是内核空间。其实,这个4G的地址空间是不存在的,也就是我们所说的虚拟内存空间。 那虚拟内存空间...

HelloRookie ⋅ 39分钟前 ⋅ 0

myatis #{}与${}区别及原理

https://blog.csdn.net/wo541075754/article/details/54292751

李道福 ⋅ 42分钟前 ⋅ 0

三分钟学会如何在函数计算中使用 puppeteer

摘要: 使用 puppeteer 结合函数计算,可以快速的构建弹性的服务完成各种功能,包括:生成网页截图或者 PDF、高级爬虫,可以爬取大量异步渲染内容的网页、模拟键盘输入、表单自动提交、登录网...

猫耳m ⋅ 43分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部