如何在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
How to change fontFamily of TextView in Android
提问by Tarik
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't really need to define my own TypeFace but all I need is something different from what it shows right now.
所以我想更改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"
/>
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)
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 font
under res
directory .Download the font which ever you want and paste it inside font
folder. The structure should be some thing like below
font
在res
目录下创建一个文件font
夹。下载您想要的字体并将其粘贴到文件夹中。结构应该像下面这样
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.xml
in 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.
回答by Joaquin Iurchuk
If you want it programatically, you could use
如果你想以编程方式,你可以使用
label.setTypeface(Typeface.SANS_SERIF, Typeface.ITALIC);
Where SANS_SERIF
you can use:
在哪里SANS_SERIF
可以使用:
DEFAULT
DEFAULT_BOLD
MONOSPACE
SANS_SERIF
SERIF
DEFAULT
DEFAULT_BOLD
MONOSPACE
SANS_SERIF
SERIF
And where ITALIC
you can use:
ITALIC
您可以在哪里使用:
BOLD
BOLD_ITALIC
ITALIC
NORMAL
BOLD
BOLD_ITALIC
ITALIC
NORMAL
All is stated on 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 TypeFace
in your Code.
你想要的是不可能的。您必须需要TypeFace
在您的代码中进行设置。
In XML
what 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 Arial
you need to set type face in your code.
因为Arial
您需要在代码中设置字体。