Android修改字体样式的示例代码

Android修改字体样式的示例代码,第1张

概述在Android实际开发中根据UI的设计图,经常要去改变系统默认的字体样式这样做会使apk变大很多啊

在AndroID实际开发中根据UI的设计图,经常要去改变系统默认的字体样式

这样做会使apk变大很多啊

而且为什么androID要使用ios的字体-_-#

单独设置字体样式

(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

  <com.test.Fontfamily.CustomTextVIEw    androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:padding="6dp"    androID:text="自定义字体"    androID:textSize="24dp"    />

(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<String,SoftReference<Typeface>> 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;  }  /**   * <p>Replace the Font of specifIEd vIEw and it's children</p>   *   * @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));  }  /**   * <p>Replace the Font of specifIEd vIEw and it's children</p>   *   * @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,FontPath),style);  }  /**   * <p>Replace the Font of specifIEd vIEw and it's children</p>   *   * @param root   The root vIEw.   * @param FontPath The full path to the Font data.   */  public voID replaceFontFromfile(@NonNull VIEw root,createTypefaceFromfile(FontPath));  }  /**   * <p>Replace the Font of specifIEd vIEw and it's children</p>   *   * @param root   The root vIEw.   * @param FontPath The full path to the Font data.   * @param style  One of {@link Typeface#norMAL},{@link Typeface#BolD_ITAliC}   */  public voID replaceFontFromfile(@NonNull VIEw root,createTypefaceFromfile(FontPath),style);  }  /**   * <p>Replace the Font of specifIEd vIEw and it's children with specifIEd typeface</p>   */  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  }  /**   * <p>Replace the Font of specifIEd vIEw and it's children with specifIEd typeface and text style</p>   *   * @param style One of {@link Typeface#norMAL},{@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,typeface,style);      }    } // else return  }  /**   * <p>Create a Typeface instance with specifIEd Font file</p>   *   * @param FontPath Font file path relative to 'assets' directory.   * @return Return created typeface instance.   */  private Typeface createTypefaceFromAsset(Context context,String FontPath)  {    SoftReference<Typeface> 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<Typeface> 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;  }  /**   * <p>Replace system default Font. <b>Note:</b>you should also add code below to your app theme in styles.xml. </p>   * {@code <item name="androID:typeface">monospace</item>}   * <p>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.</p>   *   * @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));  }  /**   * <p>Replace system default Font. <b>Note:</b>you should also add code below to your app theme in styles.xml. </p>   * {@code <item name="androID:typeface">monospace</item>}   * <p>The best place to call this method is {@link Application#onCreate()},you need to invalID the vIEw to make it effective.</p>   *   * @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));  }  /**   * <p>Replace system default Font. <b>Note:</b>you should also add code below to your app theme in styles.xml. </p>   * {@code <item name="androID:typeface">monospace</item>}   * <p>The best place to call this method is {@link Application#onCreate()},you need to invalID the vIEw to make it effective.</p>   */  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();    }  }}

阅读源码发现这里面主要方法有

replaceFont()

替换一个页面中的所有字体。用递归的方式去查找vIEw是否是TextVIEw或者TextVIEw的子类,然后进行替换。不过这种方法效率不高

用法:在页面中

FontUtils.getInstance().replaceFontFromAsset(VIEw root,String FontPath)

modifyObjectFIEld()

替换App所有字体。利用反射替换系统默认字体

用法:

a.新建一个BaseApplication继承Application在onCreate方法中

FontUtils.getInstance().replaceSystemDefaultFontFromAsset(this,"Fonts/NotoSansCJKsc-Thin.otf");

b.在Apptheme中添加

<item name="androID:typeface">monospace</item>

c.清单文件中使用BaseApplication

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的Android修改字体样式的示例代码全部内容,希望文章能够帮你解决Android修改字体样式的示例代码所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1143989.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存