如何在Android中更改TextView的fontFamily

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12128331/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:50:05  来源:igfitidea点击:

How to change fontFamily of TextView in Android

androidandroid-layouttextviewtypeface

提问by Tarik

So I'd like to change the android:fontFamilyin Android but I don't see any pre-defined fonts in Android. How do I select one of the pre-defined ones? I don't really need to define my own TypeFace but all I need is something different from what it shows right now.

所以我想更改android:fontFamilyAndroid 中的 ,但我在 Android 中没有看到任何预定义的字体。我如何选择其中一个预定义的?我真的不需要定义我自己的 TypeFace,但我需要的只是与它现在显示的不同。

<TextView
    android:id="@+id/HeaderText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="52dp"
    android:gravity="center"
    android:text="CallerBlocker"
    android:textSize="40dp"
    android:fontFamily="Arial"
 />

It seems what I did up there won't really work! BTW android:fontFamily="Arial"was a stupid attempt!

看来我在那里做的真的行不通!顺便说一句,这android:fontFamily="Arial"是一次愚蠢的尝试!

回答by Jakob Eriksson

From android 4.1 / 4.2 / 5.0, the following Robotofont families are available:

从 android 4.1 / 4.2 / 5.0 开始,以下Roboto字体系列可用:

android:fontFamily="sans-serif"           // roboto regular
android:fontFamily="sans-serif-light"     // roboto light
android:fontFamily="sans-serif-condensed" // roboto condensed
android:fontFamily="sans-serif-black"     // roboto black
android:fontFamily="sans-serif-thin"      // roboto thin (android 4.2)
android:fontFamily="sans-serif-medium"    // roboto medium (android 5.0)

enter image description here

在此处输入图片说明

in combination with

结合

android:textStyle="normal|bold|italic"

this 16 variants are possible:

这 16 种变体是可能的:

  • Roboto regular
  • Roboto italic
  • Roboto bold
  • Roboto bold italic
  • Roboto-Light
  • Roboto-Light italic
  • Roboto-Thin
  • Roboto-Thin italic
  • Roboto-Condensed
  • Roboto-Condensed italic
  • Roboto-Condensed bold
  • Roboto-Condensed bold italic
  • Roboto-Black
  • Roboto-Black italic
  • Roboto-Medium
  • Roboto-Medium italic
  • 机器人常规
  • 机器人斜体
  • Roboto 加粗
  • Roboto 粗斜体
  • Roboto-Light
  • Roboto-Light 斜体
  • 机器人薄
  • Roboto-细斜体
  • Roboto-Condensed
  • Roboto-Condensed斜体
  • Roboto-Condensed 粗体
  • Roboto-Condensed 粗斜体
  • Roboto-Black
  • Roboto-黑色斜体
  • 机器人媒体
  • Roboto-中斜体

fonts.xml

fonts.xml

<?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>

回答by Stefan Beike

This is the way to set the font programmatically:

这是以编程方式设置字体的方法:

TextView tv = (TextView) findViewById(R.id.appname);
Typeface face = Typeface.createFromAsset(getAssets(),
            "fonts/epimodem.ttf");
tv.setTypeface(face);

put the font file in your assets folder. In my case I created a subdirectory called fonts.

将字体文件放在您的资产文件夹中。就我而言,我创建了一个名为 fonts 的子目录。

EDIT:If you wonder where is your assets folder see this question

编辑:如果您想知道您的资产文件夹在哪里,请查看此问题

回答by Manohar Reddy

Starting from Android-Studio 3.0its very easy to change font family

Android-Studio 3.0开始 ,更改字体系列非常容易

Using support library 26, it will work on devices running Android API version 16 and higher

使用支持库 26,它将适用于运行 Android API 版本 16 及更高版本的设备

Create a folder fontunder resdirectory .Download the font which ever you want and paste it inside fontfolder. The structure should be some thing like below

fontres目录下创建一个文件font夹。下载您想要的字体并将其粘贴到文件夹中。结构应该像下面这样

Here

这里

Note:As of Android Support Library 26.0, you must declare both sets of attributes ( android: and app: ) to ensure your fonts load on devices running Api 26 or lower.

注意:从 Android 支持库 26.0 开始,您必须声明两组属性( android: 和 app: )以确保您的字体在运行 Api 26 或更低版本的设备上加载。

Now you can change font in layoutusing

现在,您可以更改字体的布局使用

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

To change Programatically

编程方式更改

 Typeface typeface = getResources().getFont(R.font.myfont);
   //or to support all versions use
Typeface typeface = ResourcesCompat.getFont(context, R.font.myfont);
 textView.setTypeface(typeface);  

To change font using styles.xmlcreate a style

使用styles.xml更改字体创建样式

 <style name="Regular">
        <item name="android:fontFamily">@font/dancing_script</item>
        <item name="fontFamily">@font/dancing_script</item>
        <item name="android:textStyle">normal</item>
 </style>

and apply this style to TextView

并将这种风格应用于 TextView

  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    style="@style/Regular"/>

you can also Create your own font family

您还可以创建自己的字体系列

-Right-click the font folder and go to New > Font resource file. The New Resource File window appears.

-右键单击字体文件夹,然后转到新建 > 字体资源文件。出现“新建资源文件”窗口。

-Enter the file name, and then click OK. The new font resource XML opens in the editor.

-输入文件名,然后单击确定。新字体资源 XML 在编辑器中打开。

Write your own font family here , for example

例如,在此处编写您自己的字体系列

<font-family xmlns:android="http://schemas.android.com/apk/res/android">
    <font
        android:fontStyle="normal"
        android:fontWeight="400"
        android:font="@font/lobster_regular" />
    <font
        android:fontStyle="italic"
        android:fontWeight="400"
        android:font="@font/lobster_italic" />
</font-family>

this is simply a mapping of a specific fontStyle and fontWeight to the font resource which will be used to render that specific variant. Valid values for fontStyle are normal or italic; and fontWeight conforms to the CSS font-weight specification

这只是将特定 fontStyle 和 fontWeight 映射到将用于呈现该特定变体的字体资源。fontStyle 的有效值为 normal 或 italic;和 fontWeight 符合CSS font-weight 规范

1.To changefontfamily in layoutyou can write

1.更改布局中的字体系列,您可以编写

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

2.To Change Programmatically

2.编程方式改变

 Typeface typeface = getResources().getFont(R.font.lobster);
   //or to support all versions use
Typeface typeface = ResourcesCompat.getFont(context, R.font.lobster);
 textView.setTypeface(typeface);  

To change font of entire AppAdd these two lines in AppTheme

改变整个应用程序的字体添加在AppTheme这两行

 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
     <item name="android:fontFamily">@font/your_font</item>
     <item name="fontFamily">@font/your_font</item>
  </style>

See the Documentation, Android Custom Fonts TutorialFor more info

有关更多信息,请参阅文档Android 自定义字体教程

回答by Jared Rummler

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

我不得不/system/etc/fonts.xml在最近的一个项目中解析。以下是 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):

这是解析器(基于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();

回答by Raghav Sood

Android doesn't allow you to set custom fonts from the XML layout. Instead, you must bundle the specific font file in your app's assets folder, and set it programmatically. Something like:

Android 不允许您从 XML 布局设置自定义字体。相反,您必须将特定字体文件捆绑在应用程序的资产文件夹中,并以编程方式进行设置。就像是:

TextView textView = (TextView) findViewById(<your TextView ID>);
Typeface typeFace = Typeface.createFromAsset(getAssets(), "<file name>");
textView.setTypeface(typeFace);

Note that you can only run this code after setContentView() has been called. Also, only some fonts are supported by Android, and should be in a .ttf (TrueType)or .otf (OpenType)format. Even then, some fonts may not work.

请注意,您只能在调用 setContentView() 后运行此代码。此外,Android 仅支持某些字体,并且应采用 a.ttf (TrueType).otf (OpenType)格式。即使这样,某些字体也可能无法使用。

Thisis a font that definitely works on Android, and you can use this to confirm that your code is working in case your font file isn't supported by Android.

是一种绝对适用于 Android 的字体,如果 Android 不支持您的字体文件,您可以使用它来确认您的代码是否正常工作。

Android O Update: This is now possible with XML in Android O, based on Roger's comment.

Android O 更新:根据 Roger 的评论,现在可以在 Android O 中使用XML

回答by Oded Breiner

To set Roboto programmatically:

以编程方式设置 Roboto:

paint.setTypeface(Typeface.create("sans-serif-thin", Typeface.NORMAL));

回答by biegleux

It's the same as android:typeface.

它与android:typeface.

built-in fonts are:

内置字体有:

  • normal
  • sans
  • serif
  • monospace
  • 普通的
  • 衬线
  • 等宽

See android:typeface.

参见android:typeface

回答by Joaquin Iurchuk

If you want it programatically, you could use

如果你想以编程方式,你可以使用

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

Where SANS_SERIFyou can use:

在哪里SANS_SERIF可以使用:

  • DEFAULT
  • DEFAULT_BOLD
  • MONOSPACE
  • SANS_SERIF
  • SERIF
  • DEFAULT
  • DEFAULT_BOLD
  • MONOSPACE
  • SANS_SERIF
  • SERIF

And where ITALICyou can use:

ITALIC您可以在哪里使用:

  • BOLD
  • BOLD_ITALIC
  • ITALIC
  • NORMAL
  • BOLD
  • BOLD_ITALIC
  • ITALIC
  • NORMAL

All is stated on Android Developers

一切都在 Android Developers 上说明

回答by gauravdott

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

我正在使用Chris Jenx 的优秀库Calligraphy,旨在允许您在您的 android 应用程序中使用自定义字体。试一试!

回答by Mohsin Naeem

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

你想要的是不可能的。您必须需要TypeFace在您的代码中进行设置。

In XMLwhat you can do is

XML你可以做什么

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

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

除此之外,您无法使用 XML 中的字体。:)

For Arialyou need to set type face in your code.

因为Arial您需要在代码中设置字体。