在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
  • Android修改字体样式_第1张图片

     

  • ※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

Android修改字体样式_第2张图片

(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. 样式 主题 对话框 国际化
  2. 【android开发】styles.xml常用的设置属性汇总
  3. android Button组件的属性和方法
  4. Android 设置没有 actionBar的 样式
  5. EditText的属性:android:selectAllOnFocus
  6. android ListView 属性
  7. android listview实现表格样式
  8. 自定义控件attrs文件里的属性
  9. Android之自定义ListView滚动条样式

随机推荐

  1. android之点击事件ImageView切换
  2. android 游戏开发-libgdx(一)
  3. android 线程方式打印log到sd卡
  4. android开机启动代码
  5. android 入门 Gallery
  6. Android(安卓)断点续传
  7. android 手电筒demo
  8. android Thread和Runnable的区别
  9. android 古怪问题解决集合
  10. Android动态改变TextView字体颜色