如何更改 a 中的字体TextView
,默认情况下显示为 Arial?如何将其更改为Helvetica
?
16 回答
首先,默认不是 Arial。默认为 Droid Sans。
其次,要更改为不同的内置字体,请android:typeface
在布局 XML 或setTypeface()
Java 中使用。
第三,Android 中没有 Helvetica 字体。内置选项是 Droid Sans ( sans
)、Droid Sans Mono ( monospace
) 和 Droid Serif ( serif
)。虽然您可以将自己的字体与您的应用程序捆绑在一起并通过 使用它们,但请setTypeface()
记住字体文件很大,并且在某些情况下需要许可协议(例如,Helvetica,一种 Linotype 字体)。
编辑
Android 设计语言依赖于传统的排版工具,例如比例、空间、节奏和与底层网格的对齐。成功部署这些工具对于帮助用户快速了解信息屏幕至关重要。为了支持这种排版的使用,Ice Cream Sandwich 引入了一个名为 Roboto 的新字体系列,专为 UI 和高分辨率屏幕的要求而创建。
当前的 TextView 框架为 Roboto 提供了细、轻、常规和粗体的粗细,以及每个粗细的斜体样式。该框架还提供常规和粗体字重的 Roboto Condensed 变体,以及每个字重的斜体样式。
在 ICS 之后,android 包含 Roboto 字体样式,阅读更多Roboto
编辑 2
随着支持库 26 的出现,Android 现在默认支持自定义字体。您可以在res/fonts中插入新字体,这些字体可以在 XML 中或以编程方式单独设置为 TextViews。整个应用程序的默认字体也可以通过定义样式来更改。
首先下载.ttf
您需要的字体文件(arial.ttf
)。将它放在 assets
文件夹中。(在 assets 文件夹中创建名为fonts的新文件夹并将其放在其中。)使用以下代码将字体应用于您的TextView
:
Typeface type = Typeface.createFromAsset(getAssets(),"fonts/arial.ttf");
textView.setTypeface(type);
Typeface tf = Typeface.createFromAsset(getAssets(),
"fonts/DroidSansFallback.ttf");
TextView tv = (TextView) findViewById(R.id.CustomFontText);
tv.setTypeface(tf);
您可能想要创建包含所有字体的静态类。这样,您就不会多次创建可能严重影响性能的字体。只需确保在“ assets ”文件夹下创建一个名为“ fonts ”的子文件夹即可。
执行以下操作:
public class CustomFontsLoader {
public static final int FONT_NAME_1 = 0;
public static final int FONT_NAME_2 = 1;
public static final int FONT_NAME_3 = 2;
private static final int NUM_OF_CUSTOM_FONTS = 3;
private static boolean fontsLoaded = false;
private static Typeface[] fonts = new Typeface[3];
private static String[] fontPath = {
"fonts/FONT_NAME_1.ttf",
"fonts/FONT_NAME_2.ttf",
"fonts/FONT_NAME_3.ttf"
};
/**
* Returns a loaded custom font based on it's identifier.
*
* @param context - the current context
* @param fontIdentifier = the identifier of the requested font
*
* @return Typeface object of the requested font.
*/
public static Typeface getTypeface(Context context, int fontIdentifier) {
if (!fontsLoaded) {
loadFonts(context);
}
return fonts[fontIdentifier];
}
private static void loadFonts(Context context) {
for (int i = 0; i < NUM_OF_CUSTOM_FONTS; i++) {
fonts[i] = Typeface.createFromAsset(context.getAssets(), fontPath[i]);
}
fontsLoaded = true;
}
}
这样,您可以从应用程序中的任何位置获取字体。
最佳实践
TextViewPlus.java:
public class TextViewPlus extends TextView {
private static final String TAG = "TextView";
public TextViewPlus(Context context) {
super(context);
}
public TextViewPlus(Context context, AttributeSet attrs) {
super(context, attrs);
setCustomFont(context, attrs);
}
public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setCustomFont(context, attrs);
}
private void setCustomFont(Context ctx, AttributeSet attrs) {
TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus);
String customFont = a.getString(R.styleable.TextViewPlus_customFont);
setCustomFont(ctx, customFont);
a.recycle();
}
public boolean setCustomFont(Context ctx, String asset) {
Typeface typeface = null;
try {
typeface = Typeface.createFromAsset(ctx.getAssets(), asset);
} catch (Exception e) {
Log.e(TAG, "Unable to load typeface: "+e.getMessage());
return false;
}
setTypeface(typeface);
return true;
}
}
attrs.xml:(放置res/values的位置)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TextViewPlus">
<attr name="customFont" format="string"/>
</declare-styleable>
</resources>
如何使用:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:foo="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.mypackage.TextViewPlus
android:id="@+id/textViewPlus1"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:text="@string/showingOffTheNewTypeface"
foo:customFont="my_font_name_regular.otf">
</com.mypackage.TextViewPlus>
</LinearLayout>
希望这会帮助你。
上面的答案是正确的。如果您使用那段代码,请确保在“assets”文件夹下创建一个名为“fonts”的子文件夹。
整合字体创建的另一种方法...
public class Font {
public static final Font PROXIMA_NOVA = new Font("ProximaNovaRegular.otf");
public static final Font FRANKLIN_GOTHIC = new Font("FranklinGothicURWBoo.ttf");
private final String assetName;
private volatile Typeface typeface;
private Font(String assetName) {
this.assetName = assetName;
}
public void apply(Context context, TextView textView) {
if (typeface == null) {
synchronized (this) {
if (typeface == null) {
typeface = Typeface.createFromAsset(context.getAssets(), assetName);
}
}
}
textView.setTypeface(typeface);
}
}
然后在你的活动中使用......
myTextView = (TextView) findViewById(R.id.myTextView);
Font.PROXIMA_NOVA.apply(this, myTextView);
请注意,这种带有 volatile 字段的双重检查锁定习惯用法仅适用于 Java 1.5+ 中使用的内存模型。
最佳做法是使用 Android 支持库版本 26.0.0 或更高版本。
STEP 1:添加字体文件
- 在res文件夹中创建新的字体资源字典
- 添加字体文件(.ttf,.orf)
例如,当字体文件为 helvetica_neue.ttf 时,将生成 R.font.helvetica_neue
第 2 步:创建字体系列
- 在字体文件夹中添加新的资源文件
- 将每个字体文件、样式和粗细属性包含在元素中。
例如:
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
<font
android:fontStyle="normal"
android:fontWeight="400"
android:font="@font/helvetica_neue" />
</font-family>
第 3 步:使用它
在 xml 布局中:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/my_font"/>
或者为样式添加字体:
<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
<item name="android:fontFamily">@font/lobster</item>
</style>
有关更多示例,您可以关注文档:
当您的字体存储在内部时,请res/asset/fonts/Helvetica.ttf
使用以下内容:
Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/Helvetica.ttf");
txt.setTypeface(tf);
或者,如果您的字体文件存储在内部,请res/font/helvetica.ttf
使用以下内容:
Typeface tf = ResourcesCompat.getFont(this,R.font.helvetica);
txt.setTypeface(tf);
它有点旧,但我对 CustomFontLoader 类进行了一些改进,我想分享它,这样它会有所帮助。只需使用此代码创建一个新类。
import android.content.Context;
import android.graphics.Typeface;
public enum FontLoader {
ARIAL("arial"),
TIMES("times"),
VERDANA("verdana"),
TREBUCHET("trbuchet"),
GEORGIA("georgia"),
GENEVA("geneva"),
SANS("sans"),
COURIER("courier"),
TAHOMA("tahoma"),
LUCIDA("lucida");
private final String name;
private Typeface typeFace;
private FontLoader(final String name) {
this.name = name;
typeFace=null;
}
public static Typeface getTypeFace(Context context,String name){
try {
FontLoader item=FontLoader.valueOf(name.toUpperCase(Locale.getDefault()));
if(item.typeFace==null){
item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");
}
return item.typeFace;
} catch (Exception e) {
return null;
}
}
public static Typeface getTypeFace(Context context,int id){
FontLoader myArray[]= FontLoader.values();
if(!(id<myArray.length)){
return null;
}
try {
if(myArray[id].typeFace==null){
myArray[id].typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+myArray[id].name+".ttf");
}
return myArray[id].typeFace;
}catch (Exception e) {
return null;
}
}
public static Typeface getTypeFaceByName(Context context,String name){
for(FontLoader item: FontLoader.values()){
if(name.equalsIgnoreCase(item.name)){
if(item.typeFace==null){
try{
item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");
}catch (Exception e) {
return null;
}
}
return item.typeFace;
}
}
return null;
}
public static void loadAllFonts(Context context){
for(FontLoader item: FontLoader.values()){
if(item.typeFace==null){
try{
item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");
}catch (Exception e) {
item.typeFace=null;
}
}
}
}
}
然后在你的textview上使用这个代码:
Typeface typeFace=FontLoader.getTypeFace(context,"arial");
if(typeFace!=null) myTextView.setTypeface(typeFace);
我终于得到了一个非常简单的解决方案。
在应用级别 gradle中使用这些支持库,
compile 'com.android.support:appcompat-v7:26.0.2' compile 'com.android.support:support-v4:26.0.2'
然后在res文件夹中创建一个名为“font”的目录
- 将字体(ttf)文件放在该字体目录中,记住命名约定[例如名称不应包含任何特殊字符、任何大写字符和任何空格或制表符]
之后,像这样从xml引用该字体
<Button android:id="@+id/btn_choose_employee" android:layout_width="140dp" android:layout_height="40dp" android:layout_centerInParent="true" android:background="@drawable/rounded_red_btn" android:onClick="btnEmployeeClickedAction" android:text="@string/searching_jobs" android:textAllCaps="false" android:textColor="@color/white" android:fontFamily="@font/times_new_roman_test" />
在此示例中,times_new_roman_test是该字体目录中的字体 ttf 文件
import java.lang.ref.WeakReference;
import java.util.HashMap;
import android.content.Context;
import android.graphics.Typeface;
public class FontsManager {
private static FontsManager instance;
private static HashMap<String, WeakReference<Typeface>> typefaces = new HashMap<String, WeakReference<Typeface>>();
private static Context context;
private FontsManager(final Context ctx) {
if (context == null) {
context = ctx;
}
}
public static FontsManager getInstance(final Context appContext) {
if (instance == null) {
instance = new FontsManager(appContext);
}
return instance;
}
public static FontsManager getInstance() {
if (instance == null) {
throw new RuntimeException(
"Call getInstance(Context context) at least once to init the singleton properly");
}
return instance;
}
public Typeface getFont(final String assetName) {
final WeakReference<Typeface> tfReference = typefaces.get(assetName);
if (tfReference == null || tfReference.get() == null) {
final Typeface tf = Typeface.createFromAsset(context.getResources().getAssets(),
assetName);
typefaces.put(assetName, new WeakReference<Typeface>(tf));
return tf;
}
return tfReference.get();
}
}
这样,您可以创建一个继承自 TextView 并在其构造函数上调用 setTypeface 的 View。
从资产中获取字体并设置为所有子项
public static void overrideFonts(final Context context, final View v) {
try {
if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++) {
View child = vg.getChildAt(i);
overrideFonts(context, child);
}
} else if (v instanceof TextView ) {
((TextView) v).setTypeface(Typeface.createFromAsset(context.getAssets(),"DroidNaskh.ttf"));// "BKOODB.TTF"));
}
} catch (Exception e) {
}
}
- 添加类 FontTextView.java:
public class FontTextView extends TextView {
String fonts[] = {"HelveticaNeue.ttf", "HelveticaNeueLight.ttf", "motschcc.ttf", "symbol.ttf"};
public FontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
public FontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
if (!isInEditMode()) {
init(attrs);
}
}
public FontTextView(Context context) {
super(context);
if (!isInEditMode()) {
init(null);
}
}
private void init(AttributeSet attrs) {
if (attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.FontTextView);
if (a.getString(R.styleable.FontTextView_font_type) != null) {
String fontName = fonts[Integer.valueOf(a.getString(R.styleable.FontTextView_font_type))];
if (fontName != null) {
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/" + fontName);
setTypeface(myTypeface);
}
a.recycle();
}
}
}
}
添加到 attrs.xml ,数字应该在数组类中的顺序。
<declare-styleable name="FontTextView"> <attr name="font_type" format="enum"> <enum name="HelveticaNeue" value="0"/> <enum name="HelveticaNeueLight" value="1"/> <enum name="motschcc" value="2"/> <enum name="symbol" value="3"/> </attr>
Android 使用 Roboto 字体,这是一种非常漂亮的字体,具有几种不同的粗细(常规、轻、薄、浓缩),在高密度屏幕上看起来很棒。
检查以下链接以检查机器人字体:
回到您的问题,如果您想更改应用程序中所有 TextView/Button的字体,请尝试将以下代码添加到您的 styles.xml 以使用Roboto-light字体:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
......
<item name="android:buttonStyle">@style/MyButton</item>
<item name="android:textViewStyle">@style/MyTextView</item>
</style>
<style name="MyButton" parent="@style/Widget.AppCompat.Button">
<item name="android:textAllCaps">false</item>
<item name="android:fontFamily">sans-serif-light</item>
</style>
<style name="MyTextView" parent="@style/TextAppearance.AppCompat">
<item name="android:fontFamily">sans-serif-light</item>
</style>
并且不要忘记在您的 AndroidManifest.xml 中使用“AppTheme”
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
......
</application>
也许更简单一些:
public class Fonts {
public static HashSet<String,Typeface> fonts = new HashSet<>();
public static Typeface get(Context context, String file) {
if (! fonts.contains(file)) {
synchronized (this) {
Typeface typeface = Typeface.createFromAsset(context.getAssets(), name);
fonts.put(name, typeface);
}
}
return fonts.get(file);
}
}
// Usage
Typeface myFont = Fonts.get("arial.ttf");
(请注意,此代码未经测试,但通常这种方法应该可以正常工作。)