Using custom font in android TextView using xml

前端 未结 10 1074
执念已碎
执念已碎 2020-11-29 17:02

I have added a custom font file to my assets/fonts folder. How do I use it from my XML?

I can use it from code as follows:

TextView text =          


        
10条回答
  •  情歌与酒
    2020-11-29 17:48

    Short answer: No. Android doesn't have built-in support for applying custom fonts to text widgets through XML.

    However, there's a workaround that's not terribly difficult to implement.

    First

    You'll need to define your own stylable. In your /res/values folder, open/create the attrs.xml file and add a declare-styleable object like so:

    
    
        
            
        
    
    

    Second

    Assuming you want to use this widget often, you should set up a simple cache for the loaded Typeface objects, since loading them from memory on the fly can take time. Something like:

    public class FontManager {
        private static FontManager instance;
    
        private AssetManager mgr;
    
        private Map fonts;
    
        private FontManager(AssetManager _mgr) {
            mgr = _mgr;
            fonts = new HashMap();
        }
    
        public static void init(AssetManager mgr) {
            instance = new FontManager(mgr);
        }
    
        public static FontManager getInstance() {
            if (instance == null) {
                // App.getContext() is just one way to get a Context here
                // getContext() is just a method in an Application subclass
                // that returns the application context
                AssetManager assetManager = App.getContext().getAssets();
                init(assetManager);
            }
            return instance;
        }
    
        public Typeface getFont(String asset) {
            if (fonts.containsKey(asset))
                return fonts.get(asset);
    
            Typeface font = null;
    
            try {
                font = Typeface.createFromAsset(mgr, asset);
                fonts.put(asset, font);
            } catch (Exception e) {
    
            }
    
            if (font == null) {
                try {
                    String fixedAsset = fixAssetFilename(asset);
                    font = Typeface.createFromAsset(mgr, fixedAsset);
                    fonts.put(asset, font);
                    fonts.put(fixedAsset, font);
                } catch (Exception e) {
    
                }
            }
    
            return font;
        }
    
        private String fixAssetFilename(String asset) {
            // Empty font filename?
            // Just return it. We can't help.
            if (TextUtils.isEmpty(asset))
                return asset;
    
            // Make sure that the font ends in '.ttf' or '.ttc'
            if ((!asset.endsWith(".ttf")) && (!asset.endsWith(".ttc")))
                asset = String.format("%s.ttf", asset);
    
            return asset;
        }
    }
    

    This one will allow you to use .ttc file extensions, but it's untested.

    Third

    Create a new class that subclasses TextView. This particular example takes into account the defined XML typeface (bold, italic, etc.) and apply it to the font (assuming you're using a .ttc file).

    /**
     * TextView subclass which allows the user to define a truetype font file to use as the view's typeface.
     */
    public class FontText extends TextView {
        public FontText(Context context) {
            this(context, null);
        }
    
        public FontText(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public FontText(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
    
            if (isInEditMode())
                return;
    
            TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FontText);
    
            if (ta != null) {
                String fontAsset = ta.getString(R.styleable.FontText_typefaceAsset);
    
                if (!TextUtils.isEmpty(fontAsset)) {
                    Typeface tf = FontManager.getInstance().getFont(fontAsset);
                    int style = Typeface.NORMAL;
                    float size = getTextSize();
    
                    if (getTypeface() != null)
                        style = getTypeface().getStyle();
    
                    if (tf != null)
                        setTypeface(tf, style);
                    else
                        Log.d("FontText", String.format("Could not create a font from asset: %s", fontAsset));
                }
            }
        }
    }
    

    Finally

    Replace the instances of TextView in your XML with the fully qualified class name. Declare your custom namespace just like you would the Android namespace. Note that the "typefaceAsset" should point to a .ttf or .ttc file contained in your /assets directory.

    
    
        
    
    

提交回复
热议问题