How to change fontFamily of TextView in Android

后端 未结 30 2456
感动是毒
感动是毒 2020-11-22 01:05

So I\'d like to change the android:fontFamily in Android but I don\'t see any pre-defined fonts in Android. How do I select one of the pre-defined ones? I don\'

相关标签:
30条回答
  • 2020-11-22 01:29

    If you want it programatically, you could use

    label.setTypeface(Typeface.SANS_SERIF, Typeface.ITALIC);
    

    Where SANS_SERIF you can use:

    • DEFAULT
    • DEFAULT_BOLD
    • MONOSPACE
    • SANS_SERIF
    • SERIF

    And where ITALIC you can use:

    • BOLD
    • BOLD_ITALIC
    • ITALIC
    • NORMAL

    All is stated on Android Developers

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

    For android-studio 3 and above you can use this style and then all textView font change in app.

    create this style in your style.xml :

    <!--OverRide all textView font-->
    <style name="defaultTextViewStyle" parent="android:Widget.TextView">
            <item name="android:fontFamily">@font/your_custom_font</item>
    </style>
    

    Then use it in your theme :

    <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
            <item name="android:textViewStyle">@style/defaultTextViewStyle</item>
        </style>
    
    0 讨论(0)
  • 2020-11-22 01:31

    I am using excellent library Calligraphy by Chris Jenx designed to allow you to use custom fonts in your android application. Give it a try!

    0 讨论(0)
  • 2020-11-22 01:32

    I had to parse /system/etc/fonts.xml in a recent project. Here are the current font families as of Lollipop:

    ╔════╦════════════════════════════╦═════════════════════════════╗
    ║    ║ FONT FAMILY                ║ TTF FILE                    ║
    ╠════╬════════════════════════════╬═════════════════════════════╣
    ║  1 ║ casual                     ║ ComingSoon.ttf              ║
    ║  2 ║ cursive                    ║ DancingScript-Regular.ttf   ║
    ║  3 ║ monospace                  ║ DroidSansMono.ttf           ║
    ║  4 ║ sans-serif                 ║ Roboto-Regular.ttf          ║
    ║  5 ║ sans-serif-black           ║ Roboto-Black.ttf            ║
    ║  6 ║ sans-serif-condensed       ║ RobotoCondensed-Regular.ttf ║
    ║  7 ║ sans-serif-condensed-light ║ RobotoCondensed-Light.ttf   ║
    ║  8 ║ sans-serif-light           ║ Roboto-Light.ttf            ║
    ║  9 ║ sans-serif-medium          ║ Roboto-Medium.ttf           ║
    ║ 10 ║ sans-serif-smallcaps       ║ CarroisGothicSC-Regular.ttf ║
    ║ 11 ║ sans-serif-thin            ║ Roboto-Thin.ttf             ║
    ║ 12 ║ serif                      ║ NotoSerif-Regular.ttf       ║
    ║ 13 ║ serif-monospace            ║ CutiveMono.ttf              ║
    ╚════╩════════════════════════════╩═════════════════════════════╝
    

    Here is the parser (based off FontListParser):

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    
    import org.xmlpull.v1.XmlPullParser;
    import org.xmlpull.v1.XmlPullParserException;
    
    import android.util.Xml;
    
    /**
     * Helper class to get the current font families on an Android device.</p>
     * 
     * Usage:</p> {@code List<SystemFont> fonts = FontListParser.safelyGetSystemFonts();}</p>
     */
    public final class FontListParser {
    
        private static final File FONTS_XML = new File("/system/etc/fonts.xml");
    
        private static final File SYSTEM_FONTS_XML = new File("/system/etc/system_fonts.xml");
    
        public static List<SystemFont> getSystemFonts() throws Exception {
            String fontsXml;
            if (FONTS_XML.exists()) {
                fontsXml = FONTS_XML.getAbsolutePath();
            } else if (SYSTEM_FONTS_XML.exists()) {
                fontsXml = SYSTEM_FONTS_XML.getAbsolutePath();
            } else {
                throw new RuntimeException("fonts.xml does not exist on this system");
            }
            Config parser = parse(new FileInputStream(fontsXml));
            List<SystemFont> fonts = new ArrayList<>();
    
            for (Family family : parser.families) {
                if (family.name != null) {
                    Font font = null;
                    for (Font f : family.fonts) {
                        font = f;
                        if (f.weight == 400) {
                            break;
                        }
                    }
                    SystemFont systemFont = new SystemFont(family.name, font.fontName);
                    if (fonts.contains(systemFont)) {
                        continue;
                    }
                    fonts.add(new SystemFont(family.name, font.fontName));
                }
            }
    
            for (Alias alias : parser.aliases) {
                if (alias.name == null || alias.toName == null || alias.weight == 0) {
                    continue;
                }
                for (Family family : parser.families) {
                    if (family.name == null || !family.name.equals(alias.toName)) {
                        continue;
                    }
                    for (Font font : family.fonts) {
                        if (font.weight == alias.weight) {
                            fonts.add(new SystemFont(alias.name, font.fontName));
                            break;
                        }
                    }
                }
            }
    
            if (fonts.isEmpty()) {
                throw new Exception("No system fonts found.");
            }
    
            Collections.sort(fonts, new Comparator<SystemFont>() {
    
                @Override
                public int compare(SystemFont font1, SystemFont font2) {
                    return font1.name.compareToIgnoreCase(font2.name);
                }
    
            });
    
            return fonts;
        }
    
        public static List<SystemFont> safelyGetSystemFonts() {
            try {
                return getSystemFonts();
            } catch (Exception e) {
                String[][] defaultSystemFonts = {
                        {
                                "cursive", "DancingScript-Regular.ttf"
                        }, {
                                "monospace", "DroidSansMono.ttf"
                        }, {
                                "sans-serif", "Roboto-Regular.ttf"
                        }, {
                                "sans-serif-light", "Roboto-Light.ttf"
                        }, {
                                "sans-serif-medium", "Roboto-Medium.ttf"
                        }, {
                                "sans-serif-black", "Roboto-Black.ttf"
                        }, {
                                "sans-serif-condensed", "RobotoCondensed-Regular.ttf"
                        }, {
                                "sans-serif-thin", "Roboto-Thin.ttf"
                        }, {
                                "serif", "NotoSerif-Regular.ttf"
                        }
                };
                List<SystemFont> fonts = new ArrayList<>();
                for (String[] names : defaultSystemFonts) {
                    File file = new File("/system/fonts", names[1]);
                    if (file.exists()) {
                        fonts.add(new SystemFont(names[0], file.getAbsolutePath()));
                    }
                }
                return fonts;
            }
        }
    
        /* Parse fallback list (no names) */
        public static Config parse(InputStream in) throws XmlPullParserException, IOException {
            try {
                XmlPullParser parser = Xml.newPullParser();
                parser.setInput(in, null);
                parser.nextTag();
                return readFamilies(parser);
            } finally {
                in.close();
            }
        }
    
        private static Alias readAlias(XmlPullParser parser) throws XmlPullParserException, IOException {
            Alias alias = new Alias();
            alias.name = parser.getAttributeValue(null, "name");
            alias.toName = parser.getAttributeValue(null, "to");
            String weightStr = parser.getAttributeValue(null, "weight");
            if (weightStr == null) {
                alias.weight = 0;
            } else {
                alias.weight = Integer.parseInt(weightStr);
            }
            skip(parser); // alias tag is empty, ignore any contents and consume end tag
            return alias;
        }
    
        private static Config readFamilies(XmlPullParser parser) throws XmlPullParserException,
                IOException {
            Config config = new Config();
            parser.require(XmlPullParser.START_TAG, null, "familyset");
            while (parser.next() != XmlPullParser.END_TAG) {
                if (parser.getEventType() != XmlPullParser.START_TAG) {
                    continue;
                }
                if (parser.getName().equals("family")) {
                    config.families.add(readFamily(parser));
                } else if (parser.getName().equals("alias")) {
                    config.aliases.add(readAlias(parser));
                } else {
                    skip(parser);
                }
            }
            return config;
        }
    
        private static Family readFamily(XmlPullParser parser) throws XmlPullParserException,
                IOException {
            String name = parser.getAttributeValue(null, "name");
            String lang = parser.getAttributeValue(null, "lang");
            String variant = parser.getAttributeValue(null, "variant");
            List<Font> fonts = new ArrayList<Font>();
            while (parser.next() != XmlPullParser.END_TAG) {
                if (parser.getEventType() != XmlPullParser.START_TAG) {
                    continue;
                }
                String tag = parser.getName();
                if (tag.equals("font")) {
                    String weightStr = parser.getAttributeValue(null, "weight");
                    int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
                    boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
                    String filename = parser.nextText();
                    String fullFilename = "/system/fonts/" + filename;
                    fonts.add(new Font(fullFilename, weight, isItalic));
                } else {
                    skip(parser);
                }
            }
            return new Family(name, fonts, lang, variant);
        }
    
        private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
            int depth = 1;
            while (depth > 0) {
                switch (parser.next()) {
                case XmlPullParser.START_TAG:
                    depth++;
                    break;
                case XmlPullParser.END_TAG:
                    depth--;
                    break;
                }
            }
        }
    
        private FontListParser() {
    
        }
    
        public static class Alias {
    
            public String name;
    
            public String toName;
    
            public int weight;
        }
    
        public static class Config {
    
            public List<Alias> aliases;
    
            public List<Family> families;
    
            Config() {
                families = new ArrayList<Family>();
                aliases = new ArrayList<Alias>();
            }
    
        }
    
        public static class Family {
    
            public List<Font> fonts;
    
            public String lang;
    
            public String name;
    
            public String variant;
    
            public Family(String name, List<Font> fonts, String lang, String variant) {
                this.name = name;
                this.fonts = fonts;
                this.lang = lang;
                this.variant = variant;
            }
    
        }
    
        public static class Font {
    
            public String fontName;
    
            public boolean isItalic;
    
            public int weight;
    
            Font(String fontName, int weight, boolean isItalic) {
                this.fontName = fontName;
                this.weight = weight;
                this.isItalic = isItalic;
            }
    
        }
    
        public static class SystemFont {
    
            public String name;
    
            public String path;
    
            public SystemFont(String name, String path) {
                this.name = name;
                this.path = path;
            }
    
        }
    }
    

    Feel free to use the above class in your project. For example, you could give your users a selection of font families and set the typeface based on their preference.

    A small incomplete example:

    final List<FontListParser.SystemFont> fonts = FontListParser.safelyGetSystemFonts();
    String[] items = new String[fonts.size()];
    for (int i = 0; i < fonts.size(); i++) {
        items[i] = fonts.get(i).name;
    }
    
    new AlertDialog.Builder(this).setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            FontListParser.SystemFont selectedFont = fonts.get(which);
            // TODO: do something with the font
            Toast.makeText(getApplicationContext(), selectedFont.path, Toast.LENGTH_LONG).show();
        }
    }).show();
    
    0 讨论(0)
  • 2020-11-22 01:32

    What you want is not possible. You must need to set TypeFace in your Code.

    In XML what you can do is

    android:typeface="sans" | "serif" | "monospace"
    

    other then this you can not play much with the Fonts in XML. :)

    For Arial you need to set type face in your code.

    0 讨论(0)
  • 2020-11-22 01:32

    To set the font by program, write...

         TextView tv7 = new TextView(this);
         tv7.setText(" TIME ");    
         tv7.setTypeface(Typeface.create("sans-serif-condensed",Typeface.BOLD));
         tv7.setTextSize(12);
         tbrow.addView(tv7);
    

    The name "sans-serif-condensed" is referenced from fonts.xml file which should be created in app--> res--> values folder and it holds the fonts in it.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="font_family_light">sans-serif-light</string>
        <string name="font_family_medium">sans-serif-medium</string>
        <string name="font_family_regular">sans-serif</string>
        <string name="font_family_condensed">sans-serif-condensed</string>
        <string name="font_family_black">sans-serif-black</string>
        <string name="font_family_thin">sans-serif-thin</string>
    </resources>
    

    Hope this is clear!

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