如何在棒棒糖中为整个应用程序设置自定义字体

时间:2017-06-10 09:42:57

标签: android override typeface custom-font

我想为我的应用中的所有文字视图设置自定义字体。我在代码

下面使用
public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets)
    {
        try
        {
            final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(),customFontFileNameInAssets);
            Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
            defaultFontTypefaceField.setAccessible (true);
            defaultFontTypefaceField.set(null,customFontTypeface);
        }
        catch (Exception e)
        {
            Log.e("getMessage",e.getMessage());
            e.printStackTrace();
            //Log.e("Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
        }

    }

并调用方法如下

TypefaceUtil.overrideFont(this, "DEFAULT", getTypeFace());
        TypefaceUtil.overrideFont(this, "MONOSPACE", getTypeFace());
        TypefaceUtil.overrideFont(this, "SERIF", getTypeFace());
        TypefaceUtil.overrideFont(this, "SANS_SERIF", getTypeFace());

这个代码在Android 5之前的android工作好,但它不适用于棒棒糖。 我搜索了很多,但我找不到任何东西。

5 个答案:

答案 0 :(得分:3)

我使用Calligraphy

完成了此操作 在#onCreate()方法的Application类中

@Override
public void onCreate() {
    super.onCreate();
    CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
                            .setDefaultFontPath("fonts/Roboto-RobotoRegular.ttf")
                            .setFontAttrId(R.attr.fontPath)
                            .build()
            );
    //....
}

包装活动背景:

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}

答案 1 :(得分:2)

我通过覆盖应用程序默认字体来完成它:

创建课程 FontsOverride

public final class FontsOverride {

public static void setDefaultFont(Context context,
                                  String staticTypefaceFieldName, String fontAssetName) {
    final Typeface regular = Typeface.createFromAsset(context.getAssets(),
            fontAssetName);
    replaceFont(staticTypefaceFieldName, regular);
}

private static void replaceFont(String staticTypefaceFieldName,
                                final Typeface newTypeface) {
    try {
        final Field staticField = Typeface.class
                .getDeclaredField(staticTypefaceFieldName);
        staticField.setAccessible(true);
        staticField.set(null, newTypeface);
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
  }
}

创建Application班级,或者如果您已经拥有,则将其添加到当前班级

public class AppController extends Application {

// add a folder named `fonts` under `assets` folder
// add theme here
String customFont1 = "fonts/IRANSans-Light-web.ttf";
String customFont2 = "fonts/font2.ttf";
String customFont3 = "fonts/font3.ttf";
String customFont4 = "fonts/font4.ttf";

@Override
public void onCreate() {
    super.onCreate();
    // override default fonts
    FontsOverride.setDefaultFont(this, "DEFAULT", customFont1);
    FontsOverride.setDefaultFont(this, "MONOSPACE", customFont2);
    FontsOverride.setDefaultFont(this, "SERIF", customFont3);
    FontsOverride.setDefaultFont(this, "SANS_SERIF", customFont4);

}

}

style

中为您的主题添加字体
<!-- Application theme -->
<style name="myTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:typeface">monospace</item>
</style>

最后,将其添加到manifest标记中的Application

    <application
    android:name="path.AppController"
    android:icon="@mipmap/ic_launcher"
    android:theme="@style/myTheme"
    android:label="@string/app_name">

(我已对它进行了测试,它也适用于“Lolipop”)

答案 2 :(得分:0)

假设您选择的字体是 <TextView style="@style/TextView" android:layout_width="wrap_content" android:layout_height="wrap_content"/> ,那么您也应该实现类似

{{1}}

并像这样使用

{{1}}

答案 3 :(得分:0)

我做了一个递归函数并将其保存在我的BaseActivity中:

 public static void overrideFonts(final Context context, final View v) {
    try {
        if (v instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) v;
            for (int i = 0; i < vg.getChildCount(); i++) {
                View child = vg.getChildAt(i);
                overrideFonts(context, child);
            }
        }
        if (v.getClass() == TextView.class) {
            if (v.getTag() != null && v.getTag().toString().equalsIgnoreCase("bold")) {
                ((TextView) v).setTypeface(FontUtils.getFontBold(context));
            } else {
                ((TextView) v).setTypeface(FontUtils.getFont(context));
            }
        }

        if (v.getClass() == AppCompatTextView.class) {
            if (v.getTag() != null && v.getTag().toString().equalsIgnoreCase("bold")) {
                ((TextView) v).setTypeface(FontUtils.getFontBold(context));
            } else {
                ((TextView) v).setTypeface(FontUtils.getFont(context));
            }
        }

        if (v.getClass() == Button.class) {
            ((Button) v).setTypeface(FontUtils.getFontBold(context));
        }
        if (v.getClass() == AppCompatButton.class) {
            ((Button) v).setTypeface(FontUtils.getFontBold(context));
        }

        if (v.getClass() == TextInputLayout.class) {
            ((TextInputLayout) v).setTypeface(FontUtils.getFontBold(context));
        }
        if (v.getClass() == TextInputEditText.class) {
            ((TextInputEditText) v).setTypeface(FontUtils.getFont(context));
        }
        if (v.getClass() == AppCompatEditText.class) {
            ((AppCompatEditText) v).setTypeface(FontUtils.getFont(context));
        }
        if (v.getClass() == EditText.class) {
            if (v.getTag() != null && v.getTag().toString().equalsIgnoreCase("bold")) {
                ((EditText) v).setTypeface(FontUtils.getFontBold(context));
            } else {
                ((EditText) v).setTypeface(FontUtils.getFont(context));
            }
        }
    } catch (Exception e) {
        Log.e("Font Exception", e.toString());
    }
}

FontUtils:

public abstract class FontUtils {

    public static Typeface regular, bold;

    public static Typeface getFont(Context appContext) {
    if (regular == null) {
        regular = Typeface.createFromAsset(appContext.getAssets(), "fonts/Lato-Regular.ttf");
    }
    return regular;
    }


    public static Typeface getFontBold(Context appContext) {
    if (bold == null) {
        bold = Typeface.createFromAsset(appContext.getAssets(), "fonts/Lato-Bold.ttf");
    }
    return bold;
    }
}

您可以添加自己的案例加上我使用xml中的标记来表示粗体和常规字体

android:tag="bold"

在BaseActivity的onCreate中调用方法,如下所示:

View contentView = this.findViewById(android.R.id.content);
overrideFonts(this, contentView);

确保在活动中的setContentView之后调用super.OnCreate。

希望这有帮助。

答案 4 :(得分:0)

检查出来:Working with fonts

从I / O 2017开始,您现在可以在xml中使用以下内容:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="@font/lobster"/>

Google添加了对O设备的支持,但我也引用了:

  

支持库26.0 Beta在运行Android API 14及更高版本的设备上提供对XML字体功能的支持。