Custom fonts and XML layouts (Android)

后端 未结 18 1874
执念已碎
执念已碎 2020-11-22 07:21

I\'m trying to define a GUI layout using XML files in Android. As far as I can find out, there is no way to specify that your widgets should use a custom font (e.g. one you\

相关标签:
18条回答
  • 2020-11-22 07:23

    Old question, but I sure wish I read this answer here before I started my own search for a good solution. Calligraphy extends the android:fontFamily attribute to add support for custom fonts in your asset folder, like so:

    <TextView 
      android:text="@string/hello_world"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:fontFamily="fonts/Roboto-Bold.ttf"/>
    

    The only thing you have to do to activate it is attaching it to the Context of the Activity you're using:

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

    You can also specify your own custom attribute to replace android:fontFamily

    It also works in themes, including the AppTheme.

    0 讨论(0)
  • 2020-11-22 07:24

    There are two ways to customize fonts :

    !!! my custom font in assets/fonts/iran_sans.ttf

    Way 1 : Refrection Typeface.class ||| best way

    call FontsOverride.setDefaultFont() in class extends Application, This code will cause all software fonts to be changed, even Toasts fonts

    AppController.java

    public class AppController extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            //Initial Font
            FontsOverride.setDefaultFont(getApplicationContext(), "MONOSPACE", "fonts/iran_sans.ttf");
    
        }
    }
    

    FontsOverride.java

    public 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();
            }
        }
    }
    

    Way 2: use setTypeface

    for special view just call setTypeface() to change font.

    CTextView.java

    public class CTextView extends TextView {
    
        public CTextView(Context context) {
            super(context);
            init(context,null);
        }
    
        public CTextView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init(context,attrs);
        }
    
        public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context,attrs);
        }
    
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
            init(context,attrs);
        }
    
        public void init(Context context, @Nullable AttributeSet attrs) {
    
            if (isInEditMode())
                return;
    
            // use setTypeface for change font this view
            setTypeface(FontUtils.getTypeface("fonts/iran_sans.ttf"));
    
        }
    }
    

    FontUtils.java

    public class FontUtils {
    
        private static Hashtable<String, Typeface> fontCache = new Hashtable<>();
    
        public static Typeface getTypeface(String fontName) {
            Typeface tf = fontCache.get(fontName);
            if (tf == null) {
                try {
                    tf = Typeface.createFromAsset(AppController.getInstance().getApplicationContext().getAssets(), fontName);
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
                fontCache.put(fontName, tf);
            }
            return tf;
        }
    
    }
    
    0 讨论(0)
  • 2020-11-22 07:25

    I'm 3 years late for the party :( However this could be useful for someone who might stumble upon this post.

    I've written a library that caches Typefaces and also allow you to specify custom typefaces right from XML. You can find the library here.

    Here is how your XML layout would look like, when you use it.

    <com.mobsandgeeks.ui.TypefaceTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world"
        geekui:customTypeface="fonts/custom_font.ttf" />
    
    0 讨论(0)
  • 2020-11-22 07:25

    Using DataBinding :

    @BindingAdapter({"bind:font"})
    public static void setFont(TextView textView, String fontName){
     textView.setTypeface(Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + fontName));
    }
    

    In XML:

    <TextView
    app:font="@{`Source-Sans-Pro-Regular.ttf`}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
    

    font file must be in assets/fonts/

    0 讨论(0)
  • 2020-11-22 07:25

    It may be useful to know that starting from Android 8.0 (API level 26) you can use a custom font in XML.

    You can apply a custom font to the entire application in the following way.

    1. Put the font in the folder res/font.

    2. In res/values/styles.xml use it in the application theme. <style name="AppTheme" parent="{whatever you like}"> <item name="android:fontFamily">@font/myfont</item> </style>

    0 讨论(0)
  • 2020-11-22 07:29

    Peter's answer is the best, but it can be improved by using the styles.xml from Android to customize your fonts for all textviews in your app.

    My code is here

    0 讨论(0)
提交回复
热议问题