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

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

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

这个过程太冗长和耗时。

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

【问题讨论】:

    标签: android


    【解决方案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_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:fontFamily="@font/my_custom_font" />
    

    注意事项

    【讨论】:

    • 因为旧的那个在那个时间点是相关的。每个人都应该遵循这个答案,因为它是 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_width="wrap_content"
            android:layout_height="wrap_content"       
            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_width="wrap_content"
            android:layout_height="wrap_content"
            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_width="wrap_content"
        android:layout_height="wrap_content"
        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

      【讨论】:

        猜你喜欢
        • 2011-07-29
        • 2013-04-23
        • 2023-04-02
        • 2014-12-31
        • 1970-01-01
        • 1970-01-01
        • 2021-10-06
        • 1970-01-01
        • 2014-02-08
        相关资源
        最近更新 更多