国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android修改字體樣式的示例代碼

2019-10-22 18:24:59
字體:
來源:轉載
供稿:網友

在Android實際開發中根據UI的設計圖,經常要去改變系統默認的字體樣式

這樣做會使apk變大很多啊

而且為什么android要使用ios的字體-_-#

單獨設置字體樣式

(1)Android系統提供了幾種字體樣式可供選擇

通過設置typeface屬性或者fontFamily屬性設置

typeface屬性:

  1. normal
  2. serif
  3. sans
  4. monospace

fontFamily屬性:

  1. casual
  2. cursive
  3. serif
  4. monospace
  5. sans-serif
  6. sans-serif-condensed
  7. serif-monospace
  8. sans-serif-smallcaps

Android修改字體樣式,Android,字體樣式

※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文件,把字體樣式文件放進去

Android修改字體樣式,Android,字體樣式

在代碼中設置

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"    />

Android修改字體樣式,Android,字體樣式

(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, createTypefaceFromAsset(root.getContext(), 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, @NonNull String fontPath)  {    replaceFont(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}, {@link Typeface#ITALIC}, {@link Typeface#BOLD_ITALIC}   */  public void replaceFontFromFile(@NonNull View root, @NonNull String fontPath, int style)  {    replaceFont(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}, {@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  }  /**   * <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()}, 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 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()}, 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>   */  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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 铅山县| 富民县| 波密县| 顺平县| 土默特左旗| 林芝县| 武陟县| 稷山县| 汉阴县| 大名县| 三原县| 共和县| 黑山县| 高阳县| 华宁县| 天台县| 廊坊市| 麻江县| 上杭县| 新营市| 台前县| 阳西县| 喀喇| 故城县| 鄂托克前旗| 简阳市| 博乐市| 常山县| 彭山县| 承德市| 天峻县| 江达县| 上林县| 阜宁县| 彰化市| 常州市| 新泰市| 潮州市| 大关县| 平顶山市| 长宁区|