如何在Android中更改TextView的fontFamily


739

因此,我想android:fontFamily在Android中进行更改,但在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"
 />

看来我在那里所做的并没有真正的作用!BTW android:fontFamily="Arial"是一个愚蠢的尝试!


Answers:


1660

从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压缩斜体
  • 机械手浓缩黑体
  • Roboto压缩的粗体斜体
  • 机器人黑
  • Roboto-Black斜体
  • 机械人
  • 机械斜体

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>

17
别忘了:android:fontFamily =“ sans-serif-thin” // roboto thin
Sam Lu

6
我在roboto标本簿中看到了一个称为“黑色小帽子”的变体,但我没有设法使用它。使用android:fontFamily="sans-serif-black-small-caps"不起作用。有人知道吗
tbruyelle

3
我找不到这些字体家族中的任何一个,您在这里键入了什么。我找不到一起“ sans-serif”。
蒙蒂,

9
这是一个不错的清单。是否有人链接到此信息的来源?如果Google在易于查找的位置将其包含在文档中,那将是很好的选择,例如android:fontFamilyTextView上的文档。
克里斯托弗·佩里

8
字体的最终名单中可以找到system_fonts.xml作为解释这里
Newtonx

207

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

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

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

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


34
尽管这确实可行,但请注意,这可能会导致内存泄漏。可以使用此答案进行修复。
Charles Madere 2014年

@ScootrNova我在使用您的解决方案时收到此错误。错误:找不到字体资产gothic.ttf
Sagar Devanga 2014年

如何将此应用到整个应用程序?现在在示例中,您仅将其应用于textview
Pritish Joshi 16'Feb

176

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

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

fontres目录下创建一个文件夹。下载所需字体,然后将其粘贴到font文件夹中。结构应如下所示

这里

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

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

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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_width="wrap_content"
    android:layout_height="wrap_content"
    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规范

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

 <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    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>

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


7
注意:这目前仅适用于Android Studio 3.0预览版。它在Android Studio 2.3.3上对我不起作用。希望能节省一些时间!
Tash Pemhiwa

2
既然不能这样做,getResources()怎么能从片段中获取字体呢? 编辑:在您的答案结尾的这一行为我工作: Typeface typeface = ResourcesCompat.getFont(context, R.font.myfont);
悖论

与Caligtraphy相比,在某种程度上,它使字体看起来损坏。另外fontWeight不会执行任何操作
Leo Droidcoder

@LeoDroidcoder它的工作,一定要同时使用android:fontWeightapp:fontWeight
马诺哈尔·雷迪

我检查了几次。没有效果。
Leo Droidcoder

100

我不得不解析/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添加了哪种字体?
Android开发人员

@androiddeveloper我不知道。你也许可以找到通过这里查看变化:github.com/android/platform_frameworks_base/blob/...
贾里德Rummler

@JaredRummler,原谅我的无知。为什么/什么是weight == 400?
塞缪尔

1
@Samuel我已经有一段时间没有看过这段代码了,但是400字体粗细用于“常规”或“常规”字体。例如,的Roboto-经常具有400的重量
贾里德Rummler

这需要root或其他东西吗?我在Android模拟器(版本8.1)上运行了这段代码,当我打电话时getSystemFonts(),我遇到了一个例外org.xmlpull.v1.XmlPullParserException: END_TAG expected (position:START_TAG (empty) <axis tag='wdth' stylevalue='100.0'>@219:51 in java.io.InputStreamReader@f001fb3)
Damn Vegetables

49

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)格式。即使那样,某些字体也可能不起作用。

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

Android O更新:基于Roger的评论,现在可以使用Android O中的XML进行更新。


“ Android不允许您从XML布局中设置自定义字体。” Android O中对此进行了更改,允许您创建自定义字体系列并将其以XML格式应用:developer.android.com/preview/features/working-with-fonts.html
Roger Huang

27

以编程方式设置Roboto:

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

25

与相同android:typeface

内置字体有:

  • 正常
  • 衬线
  • 等宽

参见android:typeface


4
我认为这不是一回事,但看来我们不能同时使用两者。似乎现在有不少于三个不同的属性映射到setTypeface()。也就是说fontFamilytypefacetextStyle。但是我无法终生弄清楚如何将它们精确地组合起来以解决具体的Typeface实例。有人知道吗?Google的文档没有帮助...
Rad Haring 2014年


15

我正在使用Chris Jenx设计的出色的库书法,该库旨在允许您在android应用程序中使用自定义字体。试试看!


是的,但是例如我想使用它functionanl,但不想实现所有库;)
Morozov

12

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

XML你可以做什么

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

否则,您将无法在XML中使用字体。:)

因为Arial您需要在代码中设置type face。


11

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

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

这是基于此处此处的源代码


在哪里申报?
AZ_

@AZ_就像许多资源文件一样,您可以将其放在“ res / values /”文件夹中的任何XML文件中。例如,将其放在“ res / values / fonts.xml”中。并且,要使用它,只需像这样简单地做以下示例:android:fontFamily =“ string / fontFamily__roboto_regular”
android开发者

谢谢,我正在使用这个github.com/norbsoft/android-typeface-helper,它真的很有帮助
AZ_ 2015年

好的,该库可能是通过编程方式完成的。这是针对XML的
android开发人员

9

动态地,您可以使用xml在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中,您可以在此默认字体系列中详细了解默认字体。


9
Typeface typeface = ResourcesCompat.getFont(context, R.font.font_name);
textView.setTypeface(typeface);

通过编程轻松地从res> font目录将字体设置为任何textview


7

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

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

6

通过反复试验,我了解了以下内容。

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

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

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


5

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>

///////////////////////////////////////////////////// ////////////////////////

定义布局中的“字体”存在三个相关的xml属性-android :fontFamilyandroid:typefaceandroid:textStyle。“ fontFamily”和“ textStyle”或“ typeface”和“ textStyle”的组合可用于更改文本中字体的外观,因此也可以单独使用。TextView.java中的代码片段如下所示:

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

从代码中我们可以看到:

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

4

这是在某些情况下可以使用的更简单方法。原理是在xml布局中添加不可见的TextVview并在Java代码中获取其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_width="0dp"
        android:layout_height="0dp"
        android:fontFamily="sans-serif-thin"
        android:id="@+id/textViewDescription"/>

和Java代码:

myText.setTypeface(textViewSelectedDescription.getTypeface());

它为我工作(例如在TextSwitcher中)。



4

您也可以通过在res目录下添加一个字体文件夹来实现此目的,如下所示。

在此处输入图片说明

然后,选择“字体”作为资源类型。 在此处输入图片说明

您可以从https://www.1001fonts.com/找到可用的字体,然后将TTF文件提取到该字体目录中。

在此处输入图片说明

最后,只需添加android:fontFamily:“ @ font / urfontfilename”即可更改包含textview的XML文件

在此处输入图片说明


非常好,谢谢您。idk为什么其他人有更多的星星,但是已确认您的星星可以与材质设计文本视图一起使用,app:fontFamily=但是您必须使用,其他所有内容都是相同的。
EvOlaNdLuPiZ

您救了我的命,我刚刚创建了一个名为font的文件夹,但该文件夹不起作用。反正我用你的方式,它worked.Thanks
希拉尔

4

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

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

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

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

将其添加到字体文件夹,然后以XML或以编程方式使用它们。

XML-

<TextView 
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/your_font"/>

以编程方式-

 Typeface typeface = getResources().getFont(R.font.your_font);
 textView.setTypeface(typeface); 

8
更好的使用ResourcesCompat.getFont方法
Vadim Kotov,

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

3

如果要在许多具有相同字体系列的地方使用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);
    }
}

然后像下面这样在TextView中使用此自定义类:-

   <com.myapp.customview.ProximaNovaTextView
        android:id="@+id/feed_list_item_name_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="14sp"
        />

3

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

属性窗口 属性窗口

Google字体 Google字体


2

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

现在有一个新的资源类型,字体,您可以将所有应用程序字体放在res / fonts文件夹中,然后使用R.font.my_custom_font进行访问,就像您可以访问字符串 res值,可绘制 res值一样。您甚至有机会创建字体字体 xml文件,该文件将设置为您的自定义字体(关于斜体,粗体和下划线属性)。

阅读上面的链接以获取更多信息。让我们看看支持。


遗憾的是,这仍然不适用于IntelliJ(尽管在Android Studio 3.0+上像灵符一样工作)。
Dominikus K.18年

是的,但是以上用户Redman的回答仍然非常重要,因此是解决方案的必要部分。
jungledev

2

有一个不错的图书馆

    implementation 'uk.co.chrisjenx:calligraphy:2.3.0'

该库isu用于更改整个应用程序中所有视图的字体。这不适用于适配器视图,例如列表视图。为此,我们需要在每个适配器中专门添加代码
Senthilvel S

2

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

android:fontFamily="@font/my_font_in_font_folder"

1

您可以这样设置样式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"

1

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

1

以编程方式将字体添加到TextView的最简单方法是,首先在项目的Assets文件夹中添加字体文件。例如,您的字体路径如下所示:assets/fonts/my_font.otf

并将其添加到TextView中为:

科特林

val font_path = "fonts/my_font.otf"  

myTypeface = Typeface.createFromAsset(MyApplication.getInstance().assets, font_path)

textView.typeface = myTypeface

爪哇

String font_path = "fonts/my_font.otf";
Typeface myTypeface = Typeface.createFromAsset(MyApplication.getInstance().assets, font_path)
textView.setTypeface(myTypeface);

0

在这里您可以看到所有可用的fontFamily值及其对应的字体文件的名称(此文件在android 5.0+中使用)。在移动设备中,您可以在以下位置找到它:

/system/etc/fonts.xml(适用于5.0及更高版本)

(对于使用版本的android 4.4及以下版本,但我认为它的fonts.xml格式更清晰并且易于理解。)

例如,

    <!-- first font is default -->
20    <family name="sans-serif">
21        <font weight="100" style="normal">Roboto-Thin.ttf</font>
22        <font weight="100" style="italic">Roboto-ThinItalic.ttf</font>
23        <font weight="300" style="normal">Roboto-Light.ttf</font>
24        <font weight="300" style="italic">Roboto-LightItalic.ttf</font>
25        <font weight="400" style="normal">Roboto-Regular.ttf</font>
26        <font weight="400" style="italic">Roboto-Italic.ttf</font>
27        <font weight="500" style="normal">Roboto-Medium.ttf</font>
28        <font weight="500" style="italic">Roboto-MediumItalic.ttf</font>
29        <font weight="900" style="normal">Roboto-Black.ttf</font>
30        <font weight="900" style="italic">Roboto-BlackItalic.ttf</font>
31        <font weight="700" style="normal">Roboto-Bold.ttf</font>
32        <font weight="700" style="italic">Roboto-BoldItalic.ttf</font>
33    </family>

name属性name="sans-serif"family标签定义,你可以在Android中使用的值:fontFamily中。

font标签定义对应的字体文件。

在这种情况下,您可以忽略下方的源<!-- fallback fonts -->,该源用于字体的后备逻辑。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.