在Android实际开发中根据UI的设计图,经常要去改变系统

单独设置字体样式

(1)Android系统提供了几种字体样式可供选择

通过设置typeface属性或者fontFamily属性设置
typeface属性:

  • normal
  • serif
  • sans
  • monospace

fontFamily属性:

  • casual
  • cursive
  • serif
  • monospace
  • sans-serif
  • sans-serif-condensed
  • serif-monospace
  • sans-serif-smallcaps
  •  

  • ※typeface和fontFamily区别

    android:typeface属性是增加API1
    android:fontFamily在API16(4.1)中添加了属性

  • ※当同时设置typeface和fontFamily时,只有fontFamily生效

    查看一波TextView的源码

  • private void setTypefaceFromAttrs(String familyName, int typefaceIndex, int styleIndex) {        Typeface tf = null;        if (familyName != null) {            tf = Typeface.create(familyName, styleIndex);            if (tf != null) {                setTypeface(tf);                return;            }        }        switch (typefaceIndex) {            case SANS:                tf = Typeface.SANS_SERIF;                break;            case SERIF:                tf = Typeface.SERIF;                break;            case MONOSPACE:                tf = Typeface.MONOSPACE;                break;        }        setTypeface(tf, styleIndex);    }

    从方法setTypefaceFromAttrs()看,如果你有set fontFamily属性,那么typefaceattribute将被忽略。

    这边会发现这样设置typeface和fontFamily属性对中文不生效,这时候就需要引用外部的字体样式(这里谷歌设计规范推荐使用NOTO字体https://www.google.com/get/noto/)

  • (2)使用字体样式文件设置(otf,ttf文件都可以)

在assets下新建一个fonts文件,把字体样式文件放进去

在代码中设置

AssetManager mgr = getAssets();Typeface tf = Typeface.createFromAsset(mgr, "fonts/NotoSansCJKsc-Black.otf");tv_1.setTypeface(tf);

批量设置字体样式

(1)自定义TextView

public class CustomTextView extends TextView{    public CustomTextView(Context context, AttributeSet attrs)    {        super(context, attrs);    }    //重写设置字体方法    @Override    public void setTypeface(Typeface tf)    {        tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/NotoSansCJKsc-Light.otf");        super.setTypeface(tf);    }}

之后在XML布局文件中使用CustomTextView代替TextView

(2)更换整个App的字体

思路:遍历找到所有的TextView然后替换字体
百度了一下找到下面工具类

package com.test.fontfamily;import android.app.Application;import android.content.Context;import android.graphics.Typeface;import android.support.annotation.NonNull;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import java.lang.ref.SoftReference;import java.lang.reflect.Field;import java.util.HashMap;import java.util.Map;/** * Created by Administrator on 2017/10/24. */public class FontUtils{    private static final String TAG = FontUtils.class.getSimpleName();    private Map> mCache = new HashMap<>();    private static FontUtils sSingleton = null;    public static Typeface DEFAULT = Typeface.DEFAULT;    // disable instantiate    private FontUtils()    {    }    public static FontUtils getInstance()    {        // double check        if (sSingleton == null)        {            synchronized (FontUtils.class)            {                if (sSingleton == null)                {                    sSingleton = new FontUtils();                }            }        }        return sSingleton;    }    /**     * 

Replace the font of specified view and it's children

* * @param root The root view. * @param fontPath font file path relative to 'assets' directory. */ public void replaceFontFromAsset(@NonNull View root, @NonNull String fontPath) { replaceFont(root, createTypefaceFromAsset(root.getContext(), fontPath)); } /** *

Replace the font of specified view and it's children

* * @param root The root view. * @param fontPath font file path relative to 'assets' directory. * @param style One of {@link Typeface#NORMAL}, {@link Typeface#BOLD}, {@link Typeface#ITALIC}, {@link Typeface#BOLD_ITALIC} */ public void replaceFontFromAsset(@NonNull View root, @NonNull String fontPath, int style) { replaceFont(root, createTypefaceFromAsset(root.getContext(), fontPath), style); } /** *

Replace the font of specified view and it's children

* * @param root The root view. * @param fontPath The full path to the font data. */ public void replaceFontFromFile(@NonNull View root, @NonNull String fontPath) { replaceFont(root, createTypefaceFromFile(fontPath)); } /** *

Replace the font of specified view and it's children

* * @param root The root view. * @param fontPath The full path to the font data. * @param style One of {@link Typeface#NORMAL}, {@link Typeface#BOLD}, {@link Typeface#ITALIC}, {@link Typeface#BOLD_ITALIC} */ public void replaceFontFromFile(@NonNull View root, @NonNull String fontPath, int style) { replaceFont(root, createTypefaceFromFile(fontPath), style); } /** *

Replace the font of specified view and it's children with specified typeface

*/ private void replaceFont(@NonNull View root, @NonNull Typeface typeface) { if (root == null || typeface == null) { return; } if (root instanceof TextView) { // If view is TextView or it's subclass, replace it's font TextView textView = (TextView) root; // Extract previous style of TextView int style = Typeface.NORMAL; if (textView.getTypeface() != null) { style = textView.getTypeface().getStyle(); } textView.setTypeface(typeface, style); } else if (root instanceof ViewGroup) { // If view is ViewGroup, apply this method on it's child views ViewGroup viewGroup = (ViewGroup) root; for (int i = 0; i < viewGroup.getChildCount(); ++i) { replaceFont(viewGroup.getChildAt(i), typeface); } } // else return } /** *

Replace the font of specified view and it's children with specified typeface and text style

* * @param style One of {@link Typeface#NORMAL}, {@link Typeface#BOLD}, {@link Typeface#ITALIC}, {@link Typeface#BOLD_ITALIC} */ private void replaceFont(@NonNull View root, @NonNull Typeface typeface, int style) { if (root == null || typeface == null) { return; } if (style < 0 || style > 3) { style = Typeface.NORMAL; } if (root instanceof TextView) { // If view is TextView or it's subclass, replace it's font TextView textView = (TextView) root; textView.setTypeface(typeface, style); } else if (root instanceof ViewGroup) { // If view is ViewGroup, apply this method on it's child views ViewGroup viewGroup = (ViewGroup) root; for (int i = 0; i < viewGroup.getChildCount(); ++i) { replaceFont(viewGroup.getChildAt(i), typeface, style); } } // else return } /** *

Create a Typeface instance with specified font file

* * @param fontPath font file path relative to 'assets' directory. * @return Return created typeface instance. */ private Typeface createTypefaceFromAsset(Context context, String fontPath) { SoftReference typefaceRef = mCache.get(fontPath); Typeface typeface = null; if (typefaceRef == null || (typeface = typefaceRef.get()) == null) { typeface = Typeface.createFromAsset(context.getAssets(), fontPath); typefaceRef = new SoftReference<>(typeface); mCache.put(fontPath, typefaceRef); } return typeface; } private Typeface createTypefaceFromFile(String fontPath) { SoftReference typefaceRef = mCache.get(fontPath); Typeface typeface = null; if (typefaceRef == null || (typeface = typefaceRef.get()) == null) { typeface = Typeface.createFromFile(fontPath); typefaceRef = new SoftReference<>(typeface); mCache.put(fontPath, typefaceRef); } return typeface; } /** *

Replace system default font. Note:you should also add code below to your app theme in styles.xml.

* {@code monospace} *

The best place to call this method is {@link Application#onCreate()}, it will affect * whole app font.If you call this method after view is visible, you need to invalid the view to make it effective.

* * @param context {@link Context Context} * @param fontPath font file path relative to 'assets' directory. */ public void replaceSystemDefaultFontFromAsset(@NonNull Context context, @NonNull String fontPath) { replaceSystemDefaultFont(createTypefaceFromAsset(context, fontPath)); } /** *

Replace system default font. Note:you should also add code below to your app theme in styles.xml.

* {@code monospace} *

The best place to call this method is {@link Application#onCreate()}, it will affect * whole app font.If you call this method after view is visible, you need to invalid the view to make it effective.

* * @param context {@link Context Context} * @param fontPath The full path to the font data. */ public void replaceSystemDefaultFontFromFile(@NonNull Context context, @NonNull String fontPath) { replaceSystemDefaultFont(createTypefaceFromFile(fontPath)); } /** *

Replace system default font. Note:you should also add code below to your app theme in styles.xml.

* {@code monospace} *

The best place to call this method is {@link Application#onCreate()}, it will affect * whole app font.If you call this method after view is visible, you need to invalid the view to make it effective.

*/ private void replaceSystemDefaultFont(@NonNull Typeface typeface) { modifyObjectField(null, "MONOSPACE", typeface); } private void modifyObjectField(Object obj, String fieldName, Object value) { try { Field defaultField = Typeface.class.getDeclaredField(fieldName); defaultField.setAccessible(true); defaultField.set(obj, value); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }}

 

更多相关文章

  1. Android中的常用的对话框
  2. android EditText使用指南
  3. [RK3399][Android7.1] 调试笔记 --- 设置搜狗为开机默认输入法
  4. android 当系统存在多个Launcher时,如何设置开机自动进入默认的La
  5. ImageView的scaletype属性
  6. android Settings中的各个默认设置
  7. 【【【常用的ubuntu第三方工具及android命令(自存档)】】】二
  8. AndroidStudio使用ViewPagerIndicator
  9. 样式 主题 对话框 国际化

随机推荐

  1. 2016年腾讯android开发工程师面试题目
  2. EditText的简单使用
  3. android自定义UI模板图文详解
  4. Android定时任务的应用及实现
  5. Android如何同时安装相同应用程序不同版
  6. Android(安卓)UI 之 各种长度单位
  7. Android(安卓)强指针和弱指针
  8. Android(安卓)Studio com.android.dex.De
  9. Android(安卓)View从源码的角度分析事件
  10. ListView和ScrollView的下拉和上拉的回弹