order在Android下使用自定义字体已经是一个比较普遍的需求,最近做了比较深入的研究。然后按照惯例,我再发一篇Android字体修改的文章,但是写下来发现内容挺多的,所以决定拆分成几篇文章详细讲解(也许五篇文章)。主要会是一些常用的字体替换方案,最后会介绍一些全局替换方案,当然也会包括最新的“FontsinXML”方案。期待您的持续关注。本文是本系列的第五篇文章。有兴趣的可以看看之前发表过的文章。Android字体修改概述|一开始修改字体需要简单粗暴的了解Typeface的所有细节,使用反射修改字体,修改全局字体。无缝替换字体的解决方案。思路是利用Supportv7包中的AppCompatActivity控件代理,将原来的TextView替换为我们自定义的可以通过替换AppCompatDelegate对象来修改字体的FontTextView,从而达到替换字体的目的。使用这个方案的前提是你使用的是AppCompatActivity。好了,进入正题。2.Supportv7的代理思路这里说的AndroidSupportv7包中的代理思路主要是通过AppCompatDelegate实现的。我们先来了解一下它的原理。AppCompat最初出现在v7包中的时候,其实作用很小,只是为了让ApiLevel7+的设备也能使用ActionBar。在Supportv7:21版本之后,AppCompat承担了更多的责任,可以为APILevel7+设备带来MaterialColorPalette、Widget着色、ToolBar等功能。并且之前推荐的ActionBarActivity不再推荐,取而代之的是AppCompatActivity。其实AppCompatActivity的内部实现原理也和之前的ActionBarActivity不同,它是通过AppCompatDelegate实现的。AppCompatActivity将所有生命周期相关的回调都交给AppCompatDelegate。但实际上,他们并没有直接的关系。我们也可以直接使用AppCompatDelegate放到我们自己实现的Activity中,但是这样会比较麻烦,一般不推荐这样使用。1、AppCompat为什么存在?AppCompat为了支持MD的效果,需要其内部控件具备自动着色功能,可以在App设计上保持一致的体验,提高识别度。而这些在原有的UI控件中是没有的,所以它不得不重写它所需要的所有UI控件来支持这个效果。这些重写的UI控件都在android.support.v7.widget包下:可以看到这些重写的UI控件都是以AppCompat开头的,但是如果重写那么多控件,现有的项目会直接去替换它们,工作量会很大很重,所以AppCompatDelegate这个功能,它以代理的方式自动替我们使用的UI控件,是非常有必要的。2、AppCompatDelegate的工作原理在AppCompatActivity中,使用getDelegate()方法获取AppCompatDelegate对象。而这个AppCompatDelegate.create()方法就是其代理支持的实现。可以看出它是根据不同的ApiLevel实现不同的,最高可以支持ApiLevel9。虽然这里可以看出它是通过ApiLevel来进行区分和判断具体实现的,但是像AppCompatDelegateImplVxx这样的类都从高版本继承低版本。在AppCompatDelegateImplV9中,UI控件替换的代理是通过LayoutInflaterFactory接口实现的。在解析ViewTree时,会调用createView()方法获取View对象,其中,View实际上是通过mAppCompatViewInflater.createView()获取的。在mAppCompatViewInflater.createView()中,使用UI控件的名称来替换我们需要的AppCompatXxx的UI控件。所以到这里,你可以发现,如果我们还需要使用AppCompatDelegate来替换我们需要的UI控件,我们只需要实现一个AppCompatDelegate及其callActivityOnCreateView()方法即可。在AppCompatActivity的实际父类中,重写getDelegate()方法,将方法的返回值替换为之前修改的AppCompatDelegate,实现UI控件的自动替换。3、全局字体替换看到这里,相信我已经明白了AppCompatDelegate的原理,也知道了我们如何使用它来替换全局的TextView,从而达到字体替换的目的。首先,我们需要一个可以修改字体的FontTextView控件,它继承自AppCompatTextView。FontTextView控件的逻辑很简单,就是从assets中取出字体,然后设置到TextView中。在项目中,创建一个包android.support.v7.app。在其中,新建一个FontAppCompatActivity类,该类继承自AppCompatActivity。这里通过重写callActivityOnCreateView()方法,在识别为TextView后,构造并返回重写后的FontTextView,达到控件替换的目的。当然,在实际项目中,你还需要在项目中使用EditTextView、Button等自定义控件来显示文本。需要注意的是,这里的FontCompatActivity必须放在android.support.v7.app包下,否则无法从AppCompatDelegateImplV14继承。为了方便,我也把FontTextView也放到了这个包下,结构如下:到这里,基本的替换工作已经完成,我们只需要替换我们Activity的父类即可。***,运行看看效果,最新的替换。【本文为专栏作家“张扬”原创稿件,转载请微信♂联系作者获得授权】点此查看作者更多好文
