如何在 Android 中更改 TextView 的 fontFamily

Posted

技术标签:

【中文标题】如何在 Android 中更改 TextView 的 fontFamily【英文标题】:How to change fontFamily of TextView in Android 【发布时间】:2012-08-21 03:14:56 【问题描述】:

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

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

看来我在上面所做的不会真的奏效! BTW android:fontFamily="Arial" 是个愚蠢的尝试!

【问题讨论】:

查看此链接***.com/questions/2376250/… 【参考方案1】:

从 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)

结合

android:textStyle="normal|bold|italic"

这 16 种变体是可能的:

机器人常规 机器人斜体 Roboto 粗体 Roboto 粗斜体 机器人灯 Roboto-Light 斜体 Roboto-Thin Roboto-Thin 斜体 Roboto-Condensed Roboto-Condensed 斜体 Roboto-Condensed 粗体 Roboto-Condensed 粗斜体 机械黑 Roboto-黑色斜体 机器人中型 Roboto 中斜体

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>

【讨论】:

别忘了:android:fontFamily="sans-serif-thin" // 机器人瘦 我在roboto specimen book 中看到了一个名为“black small caps”的变体,但我无法使用它。使用 android:fontFamily="sans-serif-black-small-caps" 不起作用。有人知道吗? 我无法找到这些字体系列中的任何一个。您在此处键入了什么。我无法一起找到“sans-serif”。​​ 这是一个不错的列表。有没有人有这个信息来自哪里的链接?如果谷歌在他们的文档中一个容易找到的地方有这个就好了,比如在 TextView 上的 android:fontFamily 的文档。 字体的最终列表可以在system_fonts.xml中找到,如here所解释的那样【参考方案2】:

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

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

res 目录下创建一个文件夹font。下载您想要的字体并将其粘贴到font 文件夹中。结构应该如下所示

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

现在您可以使用

更改布局中的字体
<TextView
android:layout_
android:layout_
android:fontFamily="@font/dancing_script"
app:fontFamily="@font/dancing_script"/>

以编程方式进行更改

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

要使用 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>

并将此样式应用于TextView

  <TextView
    android:layout_
    android:layout_
    style="@style/Regular"/>

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

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

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

在这里写你自己的字体系列,例如

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

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

1.要在layout改变字体族,你可以写

 <TextView
    android:layout_
    android:layout_
    android:fontFamily="@font/lobster"/>

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);  

改变整个App的字体在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>

请参阅Documentation、Android Custom Fonts Tutorial 了解更多信息

【讨论】:

注意:这目前仅适用于 Android Studio 3.0 预览版。它在 Android Studio 2.3.3 上对我不起作用。希望这可以节省一些时间! 既然不能只使用getResources(),如何从片段中获取字体? 编辑:答案末尾的这一行对我有用:Typeface typeface = ResourcesCompat.getFont(context, R.font.myfont); 与 Cligtraphy 相比,它以某种方式使我的字体看起来损坏了。 fontWeight 也没有任何作用 @LeoDroidcoder 确实有效,请确保您同时使用了 android:fontWeightapp:fontWeight 右键主菜单,选择“新建”,选择“Android资源文件”。在弹出窗口中输入“字体”作为名称,从下拉“资源类型”列表中选择“字体”。点击“确定”。【参考方案3】:

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

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

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

编辑:如果您想知道资产文件夹在哪里,请参阅this question

【讨论】:

虽然这确实有效,但请注意this can create a memory leak。可以使用this answer修复。 @ScootrNova 我在使用您的解决方案时收到此错误。错误:找不到字体资源 gothic.ttf 如何将此应用于整个应用程序?现在在示例中,您仅在 textview 上应用它【参考方案4】:

我不得不在最近的一个项目中解析/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              ║
╚════╩════════════════════════════╩═════════════════════════════╝

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

    


请随意在您的项目中使用上述类。例如,您可以为用户提供一系列字体选择,并根据他们的偏好设置字体。

一个不完整的小例子:

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

【讨论】:

你知道可能是哪个版本的Android添加了哪种字体吗? @androiddeveloper 我没有。您可能可以通过查看此处的更改来发现:github.com/android/platform_frameworks_base/blob/… @JaredRummler,请原谅我的无知。为什么/什么是重量==400? @Samuel 我有一段时间没看这段代码了,但是 400 字体粗细用于“普通”或“常规”字体。例如,Roboto-Regular 的权重为 400。 这需要root还是什么?我在Android模拟器(8.1版)上运行了这段代码,当我调用getSystemFonts()时,我得到了一个异常org.xmlpull.v1.XmlPullParserException: END_TAG expected (position:START_TAG (empty) &lt;axis tag='wdth' stylevalue='100.0'&gt;@219:51 in java.io.InputStreamReader@f001fb3) 【参考方案5】:

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

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

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

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

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

【讨论】:

"Android 不允许您从 XML 布局设置自定义字体。"这已在 Android O 中进行了更改,允许您创建自定义字体系列并在 XML 中应用它们:developer.android.com/preview/features/working-with-fonts.html【参考方案6】:

以编程方式设置 Roboto:

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

【讨论】:

【参考方案7】:

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

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

SANS_SERIF 你可以在哪里使用:

DEFAULT DEFAULT_BOLD MONOSPACE SANS_SERIF SERIF

你可以在哪里使用ITALIC

BOLD BOLD_ITALIC ITALIC NORMAL

全部声明on Android Developers

【讨论】:

【参考方案8】:

Kotlin 代码 - Textview 从资源文件夹设置自定义字体

res -> font -> avenir_next_regular.ttf 设置自定义字体

textView!!.typeface = ResourcesCompat.getFont(context!!, R.font.avenir_next_regular)

【讨论】:

【参考方案9】:

android:typeface一样。

内置字体有:

正常 没有 衬线 等宽

见android:typeface。

【讨论】:

我不认为这是一回事,但似乎我们不能同时使用两者。现在似乎有不少于三个不同的属性映射到setTypeface()。即fontFamilytypefacetextStyle。但我无法终生弄清楚这些是如何精确组合来解析具体的字体实例的。有没有人弄清楚这一点? Google 的文档帮助不大......【参考方案10】:
Typeface typeface = ResourcesCompat.getFont(context, R.font.font_name);
textView.setTypeface(typeface);

以编程方式从 res>font 目录轻松将字体设置为任何 textview

【讨论】:

【参考方案11】:

我认为我为时已晚,但也许这个解决方案对其他人有帮助。要使用自定义字体,请将字体文件放在字体目录中。

textView.setTypeface(ResourcesCompat.getFont(this, R.font.lato));

【讨论】:

【参考方案12】:

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

【讨论】:

是的,但是例如我想使用它的功能,但不想实现所有库;)【参考方案13】:

一种简单的方法是在项目中添加所需的字体

转到文件->新建->新建资源目录 选择字体

这将在您的资源中创建一个新目录 font

下载您的字体 (.ttf)。我也使用https://fonts.google.com

将其添加到您的 fonts 文件夹中,然后在 XML 中或以编程方式使用它们。

XML -

<TextView 
android:id="@+id/textView"
android:layout_
android:layout_
android:fontFamily="@font/your_font"/>

以编程方式 -

 Typeface typeface = ResourcesCompat.getFont(this, R.font.your_font);
 textView.setTypeface(typeface); 

【讨论】:

更好地使用ResourcesCompat.getFont方法【参考方案14】:

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

XML你能做的是

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

除此之外,您不能在 XML 中使用字体。 :)

对于Arial,您需要在代码中设置字体。

【讨论】:

【参考方案15】:

管理字体的一种简单方法是通过资源声明它们,如下所示:

<!--++++++++++++++++++++++++++-->
<!--added on API 16 (JB - 4.1)-->
<!--++++++++++++++++++++++++++-->
<!--the default font-->
<string name="fontFamily__roboto_regular">sans-serif</string>
<string name="fontFamily__roboto_light">sans-serif-light</string>
<string name="fontFamily__roboto_condensed">sans-serif-condensed</string>

<!--+++++++++++++++++++++++++++++-->
<!--added on API 17 (JBMR1 - 4.2)-->
<!--+++++++++++++++++++++++++++++-->
<string name="fontFamily__roboto_thin">sans-serif-thin</string>

<!--+++++++++++++++++++++++++++-->
<!--added on Lollipop (LL- 5.0)-->
<!--+++++++++++++++++++++++++++-->
<string name="fontFamily__roboto_medium">sans-serif-medium</string>
<string name="fontFamily__roboto_black">sans-serif-black</string>
<string name="fontFamily__roboto_condensed_light">sans-serif-condensed-light</string>

这是基于源代码herehere

【讨论】:

在哪里申报? @AZ_ 就像许多资源文件一样,您可以将其放入任何您想要的 XML 文件中,在“res/values/”文件夹中。例如,将其放在 "res/values/fonts.xml" 中。而且,要使用它,只需像这样:android:fontFamily="string/fontFamily__roboto_regular" 谢谢,我正在使用这个github.com/norbsoft/android-typeface-helper,它真的很有帮助 好的,该库可能是用于以编程方式进行的。这里是 XML【参考方案16】:

你可以使用这个在xml中动态设置类似于android:fontFamily的fontfamily,

For Custom font:

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

For Default font:

 tv.setTypeface(Typeface.create("sans-serif-medium",Typeface.NORMAL));

这些是使用的 默认字体 系列的列表,通过替换双引号字符串 "sans-serif-medium" 来使用其中的任何一个>

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              

"mycustomfont.ttf" 是 ttf 文件。 路径将在 src/assets/fonts/mycustomfont.ttf 中,您可以在Default font family中参考更多关于默认字体的信息

【讨论】:

【参考方案17】:

如果您使用的是 Android Studio 3.5+,更改字体非常简单。在设计视图上选择文本小部件并在属性窗口上检查 fontFamily。值下拉列表包含您可以从中选择一种的所有可用字体。如果您正在寻找 Google 字体,请点击更多字体选项。

属性窗口

谷歌字体

【讨论】:

这个答案在 2020 年应该会更高【参考方案18】:

经过反复试验,我学到了以下内容。

在 *.xml 中,您可以将常用字体与以下功能结合起来,而不仅仅是字体:

 android:fontFamily="serif" 
 android:textStyle="italic"

有了这两种样式,在任何其他情况下都不需要使用字体。使用 fontfamily&textStyle 的组合范围更大。

【讨论】:

【参考方案19】:

android:fontFamily 的有效值在 /system/etc/system_fonts.xml(4.x) 或 /system/etc/fonts.xml(5.x) 中定义。但是设备制造商可能会对其进行修改,因此设置fontFamily值实际使用的字体取决于指定设备的上述文件。

在 AOSP 中,Arial 字体是有效的,但必须使用“arial”而不是“Arial”来定义,例如 android:fontFamily="arial"。快速查看 Kitkat 的 system_fonts.xml

    <family>
    <nameset>
        <name>sans-serif</name>
        <name>arial</name>
        <name>helvetica</name>
        <name>tahoma</name>
        <name>verdana</name>
    </nameset>
    <fileset>
        <file>Roboto-Regular.ttf</file>
        <file>Roboto-Bold.ttf</file>
        <file>Roboto-Italic.ttf</file>
        <file>Roboto-BoldItalic.ttf</file>
    </fileset>
</family>

/////////////////////////////////////// /////////////////////////p>

在布局中定义“字体”有三个相关的 xml 属性——android:fontFamilyandroid:typefaceandroid:textStyle强>。 “fontFamily”和“textStyle”或“typeface”和“textStyle”的组合可以用来改变文本中字体的外观,单独使用也是如此。 TextView.java 中的 sn-p 代码如下:

    private void setTypefaceFromAttrs(String familyName, int typefaceIndex, int styleIndex) 
    Typeface tf = null;
    if (familyName != null) 
        tf = Typeface.create(familyName, styleIndex);
        if (tf != null) 
            setTypeface(tf);
            return;
        
    
    switch (typefaceIndex) 
        case SANS:
            tf = Typeface.SANS_SERIF;
            break;

        case SERIF:
            tf = Typeface.SERIF;
            break;

        case MONOSPACE:
            tf = Typeface.MONOSPACE;
            break;
    
    setTypeface(tf, styleIndex);



    public void setTypeface(Typeface tf, int style) 
    if (style > 0) 
        if (tf == null) 
            tf = Typeface.defaultFromStyle(style);
         else 
            tf = Typeface.create(tf, style);
        

        setTypeface(tf);
        // now compute what (if any) algorithmic styling is needed
        int typefaceStyle = tf != null ? tf.getStyle() : 0;
        int need = style & ~typefaceStyle;
        mTextPaint.setFakeBoldText((need & Typeface.BOLD) != 0);
        mTextPaint.setTextSkewX((need & Typeface.ITALIC) != 0 ? -0.25f : 0);
     else 
        mTextPaint.setFakeBoldText(false);
        mTextPaint.setTextSkewX(0);
        setTypeface(tf);
    

从代码中我们可以看出:

    如果设置了“fontFamily”,则“字体”将被忽略。 “字体”具有标准和有限的有效值。实际上,这些值是“normal”“sans”“serif”和“monospace”,它们可以在 system_fonts.xml(4.x) 或 fonts.xml(5.x) 中找到。实际上“normal”和“sans”都是系统的默认字体。 “fontFamily”可以设置内置字体的所有字体,而“typeface”只提供“sans-serif”“serif”和“monospace”的典型字体(字体类型的三大类)世界)。 当只设置“textStyle”时,我们实际上设置了默认字体和指定样式。有效值为“正常”“粗体”“斜体”和“粗体|斜体”。

【讨论】:

【参考方案20】:

您也可以通过在 res 目录下添加一个字体文件夹来做到这一点,如下所示。

然后,选择字体作为资源类型。

你可以从https://www.1001fonts.com/找到可用的字体,然后将TTF文件解压到这个字体目录。

最后,只需通过添加 android:fontFamily:"@font/urfontfilename" 来更改包含您的 textview 的 XML 文件

【讨论】:

非常好,谢谢。不知道为什么其他人有更多的星星,但你的被确认可以使用材料设计文本视图,你必须使用app:fontFamily= 但是,其他一切都是一样的。 你救了我的命,我刚刚创建了一个名为 font 的文件夹,但它不起作用。无论如何,我用你的方式,它的工作。谢谢【参考方案21】:

这是一种更简单的方法y,在某些情况下可以使用。原理是在你的xml布局中添加一个不可见的TextVview,并在java代码中get它的typeFace

xml文件中的布局:

 <TextView
        android:text="The classic bread is made of flour hot and salty. The classic bread is made of flour hot and salty. The classic bread is made of flour hot and salty."
        android:layout_
        android:layout_
        android:fontFamily="sans-serif-thin"
        android:id="@+id/textViewDescription"/>

还有java代码:

myText.setTypeface(textViewSelectedDescription.getTypeface());

它对我有用(例如在 TextSwitcher 中)。

【讨论】:

【参考方案22】:

试试这个:

TextView textview = (TextView) findViewById(R.id.textview);

Typeface tf= Typeface.createFromAsset(getAssets(),"fonts/Tahoma.ttf");
textview .setTypeface(tf);

【讨论】:

【参考方案23】:

要通过程序设置字体,写...

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

名称“sans-serif-condensed”引用自 fonts.xml 文件,该文件应在 app--> res--> values 文件夹中创建,其中包含字体。

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

希望这很清楚!

【讨论】:

【参考方案24】:
<string name="font_family_display_4_material">sans-serif-light</string>
<string name="font_family_display_3_material">sans-serif</string>
<string name="font_family_display_2_material">sans-serif</string>
<string name="font_family_display_1_material">sans-serif</string>
<string name="font_family_headline_material">sans-serif</string>
<string name="font_family_title_material">sans-serif-medium</string>
<string name="font_family_subhead_material">sans-serif</string>
<string name="font_family_menu_material">sans-serif</string>
<string name="font_family_body_2_material">sans-serif-medium</string>
<string name="font_family_body_1_material">sans-serif</string>
<string name="font_family_caption_material">sans-serif</string>
<string name="font_family_button_material">sans-serif-medium</string>

【讨论】:

【参考方案25】:

如果您想在这么多地方使用相同字体系列的 TextView,请扩展 TextView 类并像这样设置您的字体:-

public class ProximaNovaTextView extends TextView 

    public ProximaNovaTextView(Context context) 
        super(context);

        applyCustomFont(context);
    

    public ProximaNovaTextView(Context context, AttributeSet attrs) 
        super(context, attrs);

        applyCustomFont(context);
    

    public ProximaNovaTextView(Context context, AttributeSet attrs, int defStyle) 
       super(context, attrs, defStyle);

       applyCustomFont(context);
     

    private void applyCustomFont(Context context) 
        Typeface customFont = FontCache.getTypeface("proximanova_regular.otf", context);
        setTypeface(customFont);
    

然后在 xml 中为 TextView 使用这个自定义类,如下所示:-

   <com.myapp.customview.ProximaNovaTextView
        android:id="@+id/feed_list_item_name_tv"
        android:layout_
        android:layout_
        android:textSize="14sp"
        />

【讨论】:

【参考方案26】:

我只想提一下,Android 字体的地狱即将结束,因为今年在 Google IO 上我们终于得到了这个 -> https://developer.android.com/preview/features/working-with-fonts.html

现在有一个新的资源类型 font,您可以将所有应用程序字体放在 res/fonts 文件夹中,然后使用 R.font.my_custom_font 访问,就像您可以访问 string res 值,drawable res 值等。您甚至有机会创建 font-face xml 文件,该文件将设置您的自定义字体(大约斜体、粗体和下划线 attr)。

阅读上面的链接了解更多信息。让我们看看支持。

【讨论】:

遗憾的是,这仍然不适用于 IntelliJ(尽管在 Android Studio 3.0+ 上工作起来就像一个魅力)。 是的,但是上面用户Redman的回答仍然是解决方案的必要部分。【参考方案27】:

新的字体资源允许直接使用font设置

android:fontFamily="@font/my_font_in_font_folder"

【讨论】:

【参考方案28】:

您可以像这样定义自定义 FontFamily:

/res/font/usual.xml:

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:ignore="UnusedAttribute">
    <font
        android:fontStyle="normal"
        android:fontWeight="200"
        android:font="@font/usual_regular"
        app:fontStyle="normal"
        app:fontWeight="200"
        app:font="@font/usual_regular" />

    <font
        android:fontStyle="italic"
        android:fontWeight="200"
        android:font="@font/usual_regular_italic"
        app:fontStyle="italic"
        app:fontWeight="200"
        app:font="@font/usual_regular_italic" />

    <font
        android:fontStyle="normal"
        android:fontWeight="600"
        android:font="@font/usual_bold"
        app:fontStyle="normal"
        app:fontWeight="600"
        app:font="@font/usual_bold" />

    <font
        android:fontStyle="italic"
        android:fontWeight="600"
        android:font="@font/usual_bold_italic"
        app:fontStyle="italic"
        app:fontWeight="600"
        app:font="@font/usual_bold_italic" />
</font-family>

现在你可以做

android:fontFamily="@font/usual"

假设您的其他 font 资源也在那里,带有小写字母和 _s。

【讨论】:

【参考方案29】:

您在res/layout/value/style.xml 中设置样式是这样的:

<style name="boldText">
    <item name="android:textStyle">bold|italic</item>
    <item name="android:textColor">#FFFFFF</item>
</style>

并在main.xml 文件中使用此样式:

style="@style/boldText"

【讨论】:

【参考方案30】:

对于 android-studio 3 及更高版本,您可以使用此样式,然后在应用中更改所有 textView 字体。

在您的 style.xml 中创建此样式:

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

然后在你的主题中使用它:

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

【讨论】:

以上是关于如何在 Android 中更改 TextView 的 fontFamily的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 Textview 中的字母间距?

如何更改 Textview 中的字母间距?

如何动态更改 TextView 背景颜色?

在 Android 中更改 TextView 的不透明度

无法在TextView android中更改颜色

使用android中的颜色选择器更改textview的文本颜色和背景颜色