Is it possible to set a custom font for entire of

2018-12-31 05:31发布

I need to use certain font for my entire application. I have .ttf file for the same. Is it possible to set this as default font, at application start up and then use it elsewhere in the application? When set, how do I use it in my layout XMLs?

24条回答
浮光初槿花落
2楼-- · 2018-12-31 05:41

Since the release of Android Oreo and its support library (26.0.0) you can do this easily. Refer to this answer in another question.

Basically your final style will look like this:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
   <item name="fontFamily">@font/your_font</item> <!-- target android sdk versions < 26 and > 14 -->
</style>
查看更多
孤独寂梦人
3楼-- · 2018-12-31 05:42

Tom's solution works great, but only works with TextView and EditText.

If you want to cover most of the views (RadioGroup, TextView, Checkbox...), I created a method doing that :

protected void changeChildrenFont(ViewGroup v, Typeface font){
    for(int i = 0; i < v.getChildCount(); i++){

        // For the ViewGroup, we'll have to use recursivity
        if(v.getChildAt(i) instanceof ViewGroup){
            changeChildrenFont((ViewGroup) v.getChildAt(i), font);
        }
        else{
            try {
                Object[] nullArgs = null;
                //Test wether setTypeface and getTypeface methods exists
                Method methodTypeFace = v.getChildAt(i).getClass().getMethod("setTypeface", new Class[] {Typeface.class, Integer.TYPE});
                //With getTypefaca we'll get back the style (Bold, Italic...) set in XML
                Method methodGetTypeFace = v.getChildAt(i).getClass().getMethod("getTypeface", new Class[] {});
                Typeface typeFace = ((Typeface)methodGetTypeFace.invoke(v.getChildAt(i), nullArgs));
                //Invoke the method and apply the new font with the defined style to the view if the method exists (textview,...)
                methodTypeFace.invoke(v.getChildAt(i), new Object[] {font, typeFace == null ? 0 : typeFace.getStyle()});
            }
            //Will catch the view with no such methods (listview...)
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

This method will get back the style of the view set in XML (bold, italic...) and apply them if they exists.

For the ListView, I always create an adapter, and I set the font inside getView.

查看更多
浪荡孟婆
4楼-- · 2018-12-31 05:42

I would also like to improve weston's answer for API 21 Android 5.0.

I had the same issue on my Samsung s5, when using DEFAULT font. (with the others fonts it's working fine)

I managed to make it working by setting the typeface ("sans" for example) in XML files, for each Textview or Button

<TextView
android:layout_width="match_parent"
android:layout_height="39dp"
android:textColor="@color/abs__background_holo_light"
android:textSize="12sp"
android:gravity="bottom|center"
android:typeface="sans" />

and in MyApplication Class :

public class MyApplication extends Application {
    @Override
    public void onCreate() {
    TypefaceUtil.overrideFont(getApplicationContext(), "SANS_SERIF",
    "fonts/my_font.ttf");
    }
}

Hope it helps.

查看更多
有味是清欢
5楼-- · 2018-12-31 05:43

There is a great library for custom fonts in android:Calligraphy

here is a sample how to use it.

in Gradle you need to put this line into your app's build.gradle file:

dependencies {
    compile 'uk.co.chrisjenx:calligraphy:2.2.0'
}

and then make a class that extends Application and write this code:

public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
                        .setDefaultFontPath("your font path")
                        .setFontAttrId(R.attr.fontPath)
                        .build()
        );
    }
} 

and in the activity class put this method before onCreate:

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

and the last thing your manifest file should look like this:

<application
   .
   .
   .
   android:name=".App">

and it will change the whole activity to your font! it's simple and clean!

查看更多
梦寄多情
6楼-- · 2018-12-31 05:43

in api 26 with build.gradle 3.0.0 and higher you can create a font directory in res and use this line in your style

<item name="android:fontFamily">@font/your_font</item>

for change build.gradle use this in your build.gradle dependecies

classpath 'com.android.tools.build:gradle:3.0.0'
查看更多
春风洒进眼中
7楼-- · 2018-12-31 05:43
package com.theeasylearn.demo.designdemo;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;

public class MyButton extends TextView {

    public MyButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MyButton(Context context) {
        super(context);
        init();
    }

    private void init() {

            Typeface tf =
                    Typeface.createFromAsset(
                            getContext().getAssets(), "angelina.TTF");
            setTypeface(tf);

    }

}
查看更多
登录 后发表回答