如何改变TextView上的字体?

如何改变字体在TextView,默认显示为Arial?如何将其更改为Helvetica?

501045 次浏览

首先,默认不是Arial。默认为Droid Sans。

其次,要更改为不同的内置字体,请在布局XML中使用android:typeface或在Java中使用setTypeface()

第三,Android中没有Helvetica字体。内置选项有Droid Sans (sans), Droid Sans Mono (monospace)和Droid Serif (serif)。虽然你可以将自己的字体与应用程序捆绑在一起,并通过setTypeface()使用它们,但请记住字体文件很大,在某些情况下需要许可协议(例如Helvetica,一种Linotype字体)。

编辑

Android的设计语言依赖于传统的排版工具 比如尺度、空间、节奏以及与底层网格的对齐。 成功部署这些工具对于帮助用户至关重要 快速理解一屏信息。支持这样的使用 印刷术之后,冰淇淋三明治引入了一个新的字体家族 Roboto,专门为用户界面和需求而创建 高分辨率屏幕。< / p > 当前的TextView框架提供了Roboto在薄,轻,规则 以及粗体权重,以及每个权重的斜体样式。的 框架还提供了Roboto压缩变体的规则和粗体

.

.
在ICS之后,android包含了Roboto字体样式, 阅读更多Roboto

编辑2

随着支持库26的出现,Android现在支持自定义字体通过 违约。你可以在res /字体中插入新的字体,它可以单独以XML或编程的方式设置为TextViews。android开发者文档对在这里

.xml有一个明确的指导

首先下载你需要的字体的.ttf文件(arial.ttf)。将它放在assets文件夹中。(在资产文件夹内创建名为字体的新文件夹,并将其放置在其中。)使用以下代码将字体应用到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 /值)

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

希望这对你有所帮助。

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。

它有点老,但我改进了类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);

从资产中获取字体并设置为所有子元素

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

另一种巩固字体创建的方法…

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+中使用的内存模型。

也许可以简单一点:

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

(请注意,此代码未经测试,但通常这种方法应该工作良好。)

  1. 添加类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();
}
}
}
}


  1. 添加到assets库字体
    enter image description here < / >


  1. add to 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>
    

    < / p >

< br >

  1. 从列表中选择字体
    enter image description here < / >

最佳实践是使用Android支持库26.0.0或更高版本。

步骤1:添加字体文件

  1. res文件夹中创建新的字体资源字典
  2. 添加字体文件(.ttf.orf)

例如,当字体文件为helvetica_neue.ttf时,将生成R.font.helvetica_neue

步骤2:创建字体族

  1. 字体文件夹中添加新的资源文件
  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>

第三步:使用它

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

我终于找到了一个非常简单的解决方法。

  1. 应用级gradle中使用这些支持库,

    compile 'com.android.support:appcompat-v7:26.0.2'
    compile 'com.android.support:support-v4:26.0.2'
    
  2. then create a directory named "font" inside the res folder

  3. put fonts(ttf) files in that font directory, keep in mind the naming conventions [e.g.name should not contain any special character, any uppercase character and any space or tab]
  4. After that, reference that font from xml like this

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

In this example, times_new_roman_test is a font ttf file from that font directory

Android使用Roboto字体,这是一种非常漂亮的字体,有几种不同的粗细(普通、轻、薄、浓缩),在高密度屏幕上看起来很棒。

检查下面的链接检查roboto字体:

如何在xml布局中使用Roboto

回到你的问题,如果你想改变所有的TextView/按钮在你的应用程序的字体,试着在你的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>