在运行时设置字体,TextView

42
如何在运行时设置TextView的字体? 我创建了一个TextView。
Textview tv = new TextView(this);      
tv.setTextSize(20);

我可以轻松地改变字体大小,现在我想将字体样式设置为“Verdana”。

如何做到这一点?

9个回答

73

在运行时设置内置字体:

  • 首先,为了更改字体,使用 Typeface 类。

  • 现在,在运行时,可以使用 Java 代码中的 setTypeface(Typeface) 来设置字体。

  • 在设计时,可以使用 android:typeface="serif" 设置字体。

例如:

<TextView android:text="@+id/TextView01"
 android:id="@+id/TextView01"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:textSize="30px"
 android:textStyle="italic"
 android:typeface="serif" />

如何在Android应用程序中设置自定义字体

要实现这个目标,只需在项目根目录下创建一个名为assets/的文件夹,并将字体(以TrueType或TTF格式)放入其中。例如,可以创建assets/fonts/文件夹并将TTF文件放入其中:

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

1
我在你的示例中发现了一个错误,即字体扩展名不是小写字母,而是大写字母,例如“fonts/HandmadeTypewriter.TTF”。 - Nikunj Patel
8
字体扩展名可以是大写TTF或小写ttf,它只需要与您的资产文件夹中的方式匹配即可。 - Bill Gary
@NikunjPatel,该扩展程序也可以完全删除。 - gone

5
您可以将.ttf字体文件放在您的资产文件夹中。假设字体名称为"default.ttf",您只需编写以下2行代码即可:
TextView text = new TextView(this);
text.setTypeface(Typeface.createFromAsset(getAssets(), "default.ttf"));

同时需要注意的是,不同的字体具有不同的大小。您可能需要设置字体大小为:

text.setTextSize(20);

5

您可以使用存储在“res/font”字体文件夹中的字体,例如适用于API级别16及以上的版本。

   Typeface typeface = ResourcesCompat.getFont(context, R.font.rubik_medium);
   txtView.setTypeface(typeface);

你也可以使用

   Typeface typeface = getResources().getFont(R.font.rubik_medium);
   txtView.setTypeface(typeface);

但它只支持API级别26及以上。


3

在Android 8.0中(向后兼容API版本14),引入了XML中的字体,使得从xml本身设置字体变得非常容易。

根据Android文档:

Android 8.0(API级别26)引入了一个新功能,Fonts in XML,它允许您将字体用作资源。您可以将字体文件添加到res/font/文件夹中以将字体捆绑为资源。这些字体已编译在R文件中,并自动在Android Studio中提供。您可以借助新的资源类型font访问字体资源。例如,要访问字体资源,请使用@font/myfont或R.font.myfont。

首先,在res文件夹中创建名为fontAndroid Resource Directory,然后将.ttf字体文件添加到该目录中,接着创建字体族。

创建字体族

一个字体族是一组字体文件,包括其样式和重量细节。在Android中,您可以创建一个新的字体族作为XML资源,并将其作为单个单位访问,而不是引用每个样式和重量作为单独的资源。通过这样做,系统可以根据您尝试使用的文本样式选择正确的字体。
要创建字体族,请在Android Studio中执行以下步骤:
  1. 右键单击字体文件夹,选择新建 > 字体资源文件。出现新的资源文件窗口。
  2. 输入文件名,然后点击确定。新的字体资源XML在编辑器中打开。
  3. 将每个字体文件、样式和权重属性封装在<font>元素中。以下XML演示了如何在字体资源XML中添加与字体相关的属性:

    <?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/lobster_regular" /> <font android:fontStyle="italic" android:fontWeight="400" android:font="@font/lobster_italic" /> </font-family>

然后使用以下代码在您的textView中设置字体

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="@font/lobster"/>

2

通过使用以下方法,您可以动态地设置字体族类似于xml中的android: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中。


2
这是一个小型的实用类。
public class TypefaceHelper {

    public static void setViewGroupTypeface(ViewGroup container, Typeface typeface) {
        final int children = container.getChildCount();

        for (int i = 0; i < children; i++) 
            View child = container.getChildAt(i);

            if (child instanceof TextView) {
                setTextViewTypeface((TextView) child, typeface);
            } else if (child instanceof ViewGroup) {
                setViewGroupTypeface((ViewGroup) child, typeface);
            }
        }
    }

    public static void setTextViewTypeface(TextView textView, Typeface typeface) {
        textView.setTypeface(typeface);
    }

}

对于像SpinnerListView这样的控件(即任何类型的AdapterView),它们会从适配器中生成子项,因此您需要在适配器的getView(或类似)方法中设置每个子项View的字体类型。这是因为视图可能会根据需要创建,所以在onCreate中设置Typeface将无法正常工作。


2
如果您不想使用字体并且折腾字体文件的路径(如果您放入错误的路径可能会导致应用程序崩溃),这里有另一种方法。
首先,在您的styles.xml中创建一个样式。
<style name="YourFont">
    <item name="android:fontFamily">@font/your_font</item>
</style>

然后您只需要使用以下方式添加样式

textView.setTextAppearance(context, R.style.YourFont);

1

您需要使用字体

  1. 将您想要使用的字体作为资源添加到项目中。
  2. 使用该字体创建Typeface对象:

    Typeface myFont = Typeface.createFromAsset(getAssets(), "fonts/MyFont.ttf");

  3. 将字体设置为您想要自定义的对象:

    TextView myTextView = (TextView)findViewById(R.id.my_text_view); myTextView.setTypeface(myFont);


-3

您可以使用以下代码在运行时将所有文本设置为特定字体。只需在您的Activity的onCreate方法的末尾或每当您动态创建新视图时调用setViewGroupFont方法:

private static final String FONT_NAME = "fonts/Roboto-Regular.ttf";
private static Typeface m_font = null;

public static Typeface getFont(Context p_context)
{
    if (null == m_font && null != p_context)
    {
        m_font = Typeface.createFromAsset(p_context.getApplicationContext().getAssets(), FONT_NAME);
    }
    return m_font;
}

public static void setViewGroupFont(ViewGroup p_viewGroup)
{
    if (null != p_viewGroup)
    {
        for (int currChildIndex = 0; currChildIndex < p_viewGroup.getChildCount(); currChildIndex++)
        {
            View currChildView = p_viewGroup.getChildAt(currChildIndex);

            if (ViewGroup.class.isInstance(currChildView))
            {
                setViewGroupFont((ViewGroup) currChildView);
            }
            else
            {
                try
                {
                    Method setTypefaceMethod = currChildView.getClass().getMethod("setTypeface", Typeface.class);

                    setTypefaceMethod.invoke(currChildView, getFont(p_viewGroup.getContext()));
                }
                catch (NoSuchMethodException ex)
                {
                    // Do nothing
                }
                catch (Exception ex)
                {
                    // Unexpected error setting font
                }
            }
        }
    }
}

与其使用反射,你应该检查子元素是否是TextViewViewGroup的实例。 - Joseph Earl
只需使用以下代码: TextView tv=(TextView)findViewById(R.id.custom); Typeface face=Typeface.createFromAsset(getAssets(), "fonts/HandmadeTypewriter.ttf"); tv.setTypeface(face); - LuminiousAndroid
@JosephEarl @Avin 检查是否为“TextView”是不够的,因为您还想在按钮、单选按钮组、下拉列表等控件上设置字体...(实际上,任何支持“setTypeface”方法的控件)- 这就是为什么使用反射是最通用的方法。如果您只希望设置“TextView”的字体,则可以避免使用它,但否则您需要检查每种小部件类型并相应地进行转换。 - Muzikant
1
@Muzikant Spinner 继承自 ViewGroup,而 Button 继承自 TextView,因此像我之前所说的那样,检查它是否是 TextViewViewGroup 的实例通常就足够了。 - Joseph Earl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接