如何在 .xml 文件而不是 .java 文件中设置自定义字体?

Posted

技术标签:

【中文标题】如何在 .xml 文件而不是 .java 文件中设置自定义字体?【英文标题】:How to set custom font in .xml file instead of .java file? 【发布时间】:2016-07-28 03:27:48 【问题描述】:

我正在创建一个要在其中设置自定义字体的应用程序。

但我不能在 .xml 文件中使用自定义字体,为此我需要在 .java 文件中初始化每个 TextView。

这个过程太冗长和耗时。

如果有人知道,请帮助我...

【问题讨论】:

【参考方案1】:

android API 16+

从 Android 8.0 (API 26) 开始,原生支持在 XML 中设置字体。但是,使用支持库将其扩展到 Android 4.1 (API 16)。

1。为您的项目添加字体

右键单击res 文件夹并转到新建> Android 资源目录。键入 font 作为名称,font 作为资源类型。 将您的字体复制并粘贴到新的res/font 目录中。在我的示例中,我只使用了一种字体,即常规的dancing script 字体。我将它重命名为 dancing_script.ttf 只是为了避免任何潜在的大写或非法字符的命名问题。

2。创建一个font-family XML 文件。

右键单击res/font 文件夹并选择New > Font Resource File。随心所欲地称呼它。我打电话给我的my_custom_font.xml

粘贴以下代码。请注意,属性设置了两次,一次用于android (API 26+),一次用于app (API 16+)。

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <font
        android:fontStyle="normal"
        android:fontWeight="400"
        android:font="@font/dancing_script"
        app:fontStyle="normal"
        app:fontWeight="400"
        app:font="@font/dancing_script"
        />
</font-family>

3。在 XML 中设置字体

现在您可以使用fontFamily 属性在 XML 中设置字体。

<TextView
    android:layout_
    android:layout_
    android:text="Hello World!"
    android:fontFamily="@font/my_custom_font" />

注意事项

阅读documentation 获取更多帮助。 如果您需要支持 pre-API 16,那么只需 set the font programmatically。

【讨论】:

因为旧的那个在那个时间点是相关的。每个人都应该遵循这个答案,因为它是 Android 的官方推荐。但这并不意味着以前的答案或像 Calligraphy 这样的库没有用。它们仍然可以在用户使用低于 API 级别 16 的情况下使用,我认为这种情况很少见。 将 xml 文件与 ttf 文件混合是不是一个好主意? @NocTurn,我喜欢在 xml 中设置字体的原因是它可以更多地清理代码。 @Suragch 确实如此。我一直在使用 setTypeface 直到我遇到你的答案。谢谢你:) 上述步骤是否适用于 API 低于 26(和高于 16)?【参考方案2】:

供您参考,

 public class MyTextView extends TextView 

    public MyTextView(Context context, AttributeSet attrs, int defStyle) 
        super(context, attrs, defStyle);
        init();
    

    public MyTextView(Context context, AttributeSet attrs) 
        super(context, attrs);
        init();
    

    public MyTextView(Context context) 
        super(context);
        init();
    

    public void init() 
        Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "font/yourfont.ttf");
        setTypeface(tf ,1);

    

在 XML 中,

 <you_package.MyTextView
        android:layout_
        android:layout_       
        android:textSize="20sp"
        android:text="Your text"
        />

【讨论】:

@Srinivasan 尝试在 xml 中使用它,但即使将我自己的字体放在以编程方式工作的 asserts 文件夹中,它也会在 Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "font/yourfont.ttf"); 中抛出 java.lang.NullPointerException @gikarasojo kinene 你能否给我更多信息,比如你是在 init() 方法中得到这个异常还是在 onCreate() 中找到 MyTextView。请记住字体名称及其扩展名是区分大小写的。不要忘记在 XML 中添加你的包名 @Srinivasan 我在Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/RobotoCondensed-Regular.ttf"); 线上的init() 方法中遇到了异常。我的字体是RobotoCondensed-Regular.ttf。该错误显示在 xml 预览中,并且当我运行我的应用程序时,它也发生了冲突。所以我最终使用了普通的Textview(没有扩展它)并以这种方式设置字体`Typeface typeface = Typeface.createFromAsset(getContext().getAssets(),"fonts/RobotoCondensed-Regular.ttf"); textview.setTypeface(typeface);` 我收到一个错误Caused by: android.view.InflateException: Binary XML file line #35: Error inflating class com.app.etc.BaseActivity.MyTextView Caused by: java.lang.ClassNotFoundException: Didn't find class "com.app.etc.BaseActivity.MyTextView" on path: DexPathList[[zip file "/data/app/com.app.etc-1/base.apk"],nativeLibraryDirectories=[/data/app/com.app.etc-1/lib/arm64, /system/lib64, /vendor/lib64]]【参考方案3】:

根据documentation

Android 8.0(API 级别 26)引入了一项新功能,即 XML 中的字体, 这使您可以将字体用作资源。您可以将字体文件添加到 res/font/ 文件夹将字体捆绑为资源。这些字体是 在您的 R 文件中编译并在 Android 中自动可用 工作室。您可以在新的帮助下访问字体资源 资源类型,字体。例如,要访问字体资源,请使用 @font/myfont 或 R.font.myfont。使用 XML 中的字体功能 运行 Android API 版本 14 及更高版本的设备,请使用支持 图书馆 26.

要将字体添加为资源,请在 Android 中执行以下步骤 工作室:

1.右键res文件夹,进入New > Android资源目录。将出现“新建资源目录”窗口。

2.在资源类型列表中,选择字体,然后单击确定。注意:资源目录的名称必须是字体。

3.在字体文件夹中添加您的字体文件。

创建字体系列

字体系列是一组字体文件及其样式和粗细 细节。在 Android 中,您可以创建一个新的字体系列作为 XML 资源并将其作为一个单元访问,而不是引用每个单元 样式和重量作为单独的资源。通过这样做,系统可以 根据您尝试使用的文本样式选择正确的字体。

要创建字体系列,请在 Android 中执行以下步骤 工作室:

1.右键单击字体文件夹并转到新建>字体资源文件。将出现“新建资源文件”窗口。

2.输入文件名,然后单击“确定”。新的字体资源 XML 在编辑器中打开。

3. 将每个字体文件、样式和粗细属性包含在元素中。以下 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>

在 XML 布局中使用字体

在布局 XML 文件中,将 fontFamily 属性设置为字体文件 你想访问。

<TextView
        android:layout_
        android:layout_
        android:fontFamily="@font/lobster"/>

打开属性窗口为 TextView 设置字体。选择一个 查看以打开“属性”窗口。注意:属性窗口是 仅在设计编辑器打开时可用。选择设计选项卡 在窗口底部。

展开 textAppearance 属性,然后从 字体家族列表。

为样式添加字体

打开styles.xml,给字体文件设置fontFamily属性 你想访问。

 <style name="customfontstyle" parent="@android:style/TextAppearance.Small">
    <item name="android:fontFamily">@font/lobster</item>
</style>

【讨论】:

要在运行 Android API 16 及更高版本的设备上使用 XML 中的字体功能,请使用支持库 26。【参考方案4】:

正如其他答案所暗示的,您可以使用从谷歌下载的字体: Android API 16+

在设计器中打开 textAppearance 微调器: 为您的视图选择一种字体(点击更多字体...),如下所示:

在对话框中选择您的自定义字体并将其下载到您的项目中:

现在,您可以使用 fontFamily 属性从 xml 中引用该字体:

    <Button
    android:id="@+id/btnTapMe"
    android:layout_
    android:layout_
    android:background="@drawable/rounded_button"
    android:fontFamily="@font/aclonica"

    android:text="Tap Me!"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.5"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

作为奖励,您还可以在代码中使用它: 见sn-p:

Toast toast = Toast.makeText(this, yourString, Toast.LENGTH_SHORT);
LinearLayout layout = (LinearLayout) toast.getView();
TextView tvToast = (TextView) layout.getChildAt(0);

//Here is the relevant part:
Typeface typeface = ResourcesCompat.getFont(this, R.font.aclonica);
tvToast.setTypeface(typeface);
toast.show();

【讨论】:

【参考方案5】:

您可以简单地使用自定义文本视图,例如

public class HelveticaRagularTextView extends TextView 

public HelveticaRagularTextView(Context context, AttributeSet attrs, int defStyle) 
    super(context, attrs, defStyle);
    init(attrs);


public HelveticaRagularTextView(Context context, AttributeSet attrs) 
    super(context, attrs);
    init(attrs);



public HelveticaRagularTextView(Context context) 
    super(context);
    init(null);


private void init(AttributeSet attrs) 
    // Just Change your font name
    Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), getContext().getResources().getString(R.string.font_helvetica_regular));
    setTypeface(myTypeface);

现在您可以在您的 xml 中使用 HelveticaRagularTextView。

这很容易使用

【讨论】:

我们可以像普通文本字段一样在这个类中使用所有相同的属性吗? 是的,您可以使用此类使用所有属性。您还可以使用此类查看文本的预览 好吧.. 谢谢@harsh【参考方案6】:

TextView 扩展一个自定义类并自定义类中的字体。然后您就可以在 xml 中使用该自定义 textview 类,并且您无需在代码中动态自定义字体。

祝你好运。

【讨论】:

谢谢@Mann。那是个好主意。 :)【参考方案7】:

下载你要使用的字体的ttf文件并粘贴到

src->main->assets->font.ttf

那么要使用 ttf 你需要做以下事情

要将该字体设置为特定文本,请执行以下操作

   TextView tv_the = (TextView) findViewById(R.id.the);
    Typeface face = Typeface.createFromAsset(getAssets(), "font.ttf");
    tv_the.setTypeface(face);

如果您想为整个活动设置自定义字体,请执行以下操作

final ViewGroup mContainer = (ViewGroup) findViewById(android.R.id.content).getRootView();
        final Typeface mFont = Typeface.createFromAsset(getAssets(), "badoni2.ttf");
        Parameters.setAppFont(mContainer, mFont);

并在您的应用程序中添加 Parameters

public class Parameters 

public static final void setAppFont(ViewGroup mContainer, Typeface mFont) 
    if (mContainer == null || mFont == null)
        return;

    final int mCount = mContainer.getChildCount();

    // Loop through all of the children.
    for (int i = 0; i < mCount; ++i) 
        final View mChild = mContainer.getChildAt(i);
        if (mChild instanceof TextView) 
            // Set the font if it is a TextView.
            ((TextView) mChild).setTypeface(mFont);
         else if (mChild instanceof ViewGroup) 
            // Recursively attempt another ViewGroup.
            setAppFont((ViewGroup) mChild, mFont);
        

    

试试这个,让我知道它是否适合你

【讨论】:

感谢@Rakshit 的回复。它帮助我在整个活动中设置自定义字体。如果您知道在 XML 文件中设置自定义字体,请与我分享。 @RonakSelarka 如果它有助于接受并投票支持我的回答,谢谢【参考方案8】:

Android 8.0(API 级别 26)和 Android 支持库 26 引入了对 API 的支持,以从提供程序应用程序请求字体,而不是将文件捆绑到 APK 中或让 APK 下载字体。该功能可通过支持库 26 在运行 Android API 版本 14 及更高版本的设备上使用。

请点击此链接 https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts

【讨论】:

以上是关于如何在 .xml 文件而不是 .java 文件中设置自定义字体?的主要内容,如果未能解决你的问题,请参考以下文章

如何在布局 XML 文件中设置选项卡高度?

Android - 如何在代码中设置首选项

在java中创建XML文件时传递字符串而不是节点

Android - 使用纯Java而不是XML创建应用程序?

如何使 XML 文件始终在文本编辑器而不是 XML 编辑器中打开?

在 Swift 3.0 中设置 Alamofire 自定义目标文件名而不是使用建议的DownloadDestination