如何在XML中使用指定的字体权重

Bry*_*yan 37 android android-fonts android-xml android-styles

使用XML中字体功能,您可以为字体系列指定各种字体粗细.例如:

<?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:font="@font/archivo_narrow_regular" android:fontWeight="400" android:fontStyle="normal"
        app:font="@font/archivo_narrow_regular" app:fontWeight="400" app:fontStyle="normal"/>

    <font android:font="@font/archivo_narrow_regular_italic" android:fontWeight="400" android:fontStyle="italic"
        app:font="@font/archivo_narrow_regular_italic" app:fontWeight="400" app:fontStyle="italic"/>

    <font android:font="@font/archivo_narrow_medium" android:fontWeight="500" android:fontStyle="normal"
        app:font="@font/archivo_narrow_medium" app:fontWeight="500" app:fontStyle="normal"/>

    <font android:font="@font/archivo_narrow_medium_italic" android:fontWeight="500" android:fontStyle="italic"
        app:font="@font/archivo_narrow_medium_italic" app:fontWeight="500" app:fontStyle="italic"/>

    <font android:font="@font/archivo_narrow_semibold" android:fontWeight="600" android:fontStyle="normal"
        app:font="@font/archivo_narrow_semibold" app:fontWeight="600" app:fontStyle="normal"/>

    <font android:font="@font/archivo_narrow_semibold_italic" android:fontWeight="600" android:fontStyle="italic"
        app:font="@font/archivo_narrow_semibold_italic" app:fontWeight="600" app:fontStyle="italic"/>

    <font android:font="@font/archivo_narrow_bold" android:fontWeight="700" android:fontStyle="normal"
        app:font="@font/archivo_narrow_bold" app:fontWeight="700" app:fontStyle="normal"/>

    <font android:font="@font/archivo_narrow_bold_italic" android:fontWeight="700" android:fontStyle="italic"
        app:font="@font/archivo_narrow_bold_italic" app:fontWeight="700" app:fontStyle="italic"/>

</font-family>
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚如何实际利用这些权重; 无论是在XML(布局/样式)文件中,还是在Java代码中.它们没有fontWeight可用的属性TextView,并且Typeface创建的对象ResourcesCompat.getFont(context, R.font.archivo_narrow)没有提到字体权重.

我意识到我只能指定特定的字体资源(即R.font.archivo_narrow_semibold),但那么fontWeight在该属性中有font-family什么意义呢?


更新

create(Typeface family, int weight, boolean italic)API Level 28中添加了一个新的静态方法,以及一个getWeight()实例方法.这最终使得可以fontWeight在Java代码中使用该属性; 虽然仅针对API Level 28及更高版本,但我在支持库中找不到任何类似物.

这很有用 - 并且表明该fontWeight属性在过去没有任何用途 - 但我真的希望能够在XML样式中使用权重.

Raj*_*iya 24

它看起来像android遵循web标准的字体管理和Android应用程序的大小调整.

"font-weight"属性用于定义字体的权重,例如常规或粗体.

但是对于所有其他权重,使用从100到900的数值范围.Web字体的一个挑战是大多数Web浏览器不能正常支持除普通和粗体之外的字体权重.下图描述了权重与数字定义的可能映射:

100    Extra Light or Ultra Light
200    Light or Thin
300    Book or Demi
400    Normal or Regular
500    Medium
600    Semibold, Demibold
700    Bold
800    Black, Extra Bold or Heavy
900    Extra Black, Fat, Poster or Ultra Black
Run Code Online (Sandbox Code Playgroud)

您可以在此处阅读有关字体粗细的更多信


cc_montserrat_bold.xml

<?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:font="@font/montserrat_bold"
        android:fontStyle="normal"
        android:fontWeight="700"
        app:font="@font/montserrat_bold"
        app:fontStyle="normal"
        app:fontWeight="700" />
    <font
        android:font="@font/montserrat_bolditalic"
        android:fontStyle="italic"
        android:fontWeight="700"
        app:font="@font/montserrat_bolditalic"
        app:fontStyle="italic"
        app:fontWeight="700" />

</font-family>
Run Code Online (Sandbox Code Playgroud)

cc_montserrat_regular.xml

<?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:font="@font/montserrat_regular"
        android:fontStyle="normal"
        android:fontWeight="400"
        app:font="@font/montserrat_regular"
        app:fontStyle="normal"
        app:fontWeight="400" />
    <font
        android:font="@font/montserrat_italic"
        android:fontStyle="italic"
        android:fontWeight="400"
        app:font="@font/montserrat_italic"
        app:fontStyle="italic"
        app:fontWeight="400" />


</font-family>
Run Code Online (Sandbox Code Playgroud)

Kotlin用法:

val textView = dialog.findViewById<TextView>(android.R.id.message) as TextView
val typeface = ResourcesCompat.getFont(context,R.font.cc_montserrat_regular)
        textView.typeface = typeface
Run Code Online (Sandbox Code Playgroud)

Android项目截图:

在此输入图像描述

  • 是的,但我如何*使用*各种字体权重? (9认同)
  • @Bryan,我浪费了几个小时试图找到这个非常简单的问题的答案.不知道为什么每个人都在提出荒谬的解决方法.你有没有找到解决方案? (6认同)
  • 我可以在`<font>`标签中指定`font-weight`属性,但我无法在我的代码中的其他地方找到*引用*font-weight`属性的方法(即我可以*设置*权重,我只是不能*使用*的重量).有一个[`textStyle`](https://developer.android.com/reference/android/widget/TextView.html#attr_android:textStyle)属性,但你只能指定`bold`,`italic`或`bold | italic`.例如,没有"semibold". (3认同)
  • 这看起来有点矫枉过正.`font-family`通常包含所有变体,而不仅仅是特定重量的`normal`和`italic`变体.它仍然没有解释为什么有一个`font-weight`属性,我*不能使用*. (3认同)
  • 那么为什么有 `font-weight` 属性呢?它在内部做什么?如果我没有办法参考它,它似乎没用。 (2认同)
  • @RajeshDalsaniya 我在原始问题中引用了该文档。同样,它展示了如何指定 `font-weight` 属性,但要 [*use*](https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml .html#fonts-in-code) 获取 [`Typeface`](https://developer.android.com/reference/android/graphics/Typeface.html) 实例所需的字体;它没有任何对 `font-weight` 属性的引用。 (2认同)
  • 疯狂的是,仍然没有好的兼容解决方案,疯狂的是,对作为答案发布的问题的可怕改写获得了超过 50 票 (2认同)

cac*_*acs 14

弗洛里安在关于 < API 28 的评论中是正确的,只是为了明确说明它(因为我花了很长时间试图弄清楚它是如何工作的):

Android 似乎忽略了字体系列中的所有内容,除了字体粗细 700 和 400,它textStyle分别用于粗体和非粗体。

就是这样。您可以使用常规 400/700 和斜体 400/700。其他定义似乎都没有得到使用,只有使用较新的 API,您才能真正使用它们做任何事情。如果我遗漏了一些东西,请告诉我,但这似乎是您可以控制较低 API 的全部内容-粗体与否。


系统似乎确实在寻找替代权重,因此如果您指定bold但没有定义任何权重为700,它将拉另一个权重(即使是斜体变体),但您实际上不能说“使用中等500用于此样式”-您必须创建一个单独的字体系列并明确使用它,此时您还不如指定实际字体?


为了完整起见,我已经完成了多字体系列的事情(对于我使用的每个重量,一个单独的一个 - 常规,中等等)并将它们应用到styleMaterial Design 类型比例生成器生成的s 中。类型比例使用不同的权重,例如用于Headline1 的light和用于Subtitle2 的medium但显然 Android 没有使用它们(并且它们也没有在样式层次结构中指定)。

因此,您可以通过将字体系列引用添加到生成的样式中来解决此问题:

<style name="TextAppearance.MdcTypographyStyles.Headline1" parent="TextAppearance.MaterialComponents.Headline1">
    <item name="fontFamily">@font/my_font_weight_light</item>
    <item name="android:fontFamily">@font/my_font_weight_light</item>
    <item name="android:textSize">123sp</item>
    <item name="android:letterSpacing">-0.0122</item>
</style>
Run Code Online (Sandbox Code Playgroud)

哪里my_font_weight_light.xml是仅包含字体的浅色变体的字体系列

<font-family xmlns:app="http://schemas.android.com/apk/res-auto">
    <font
        app:font="@font/my_font_light_italic"
        app:fontStyle="italic"
        app:fontWeight="400" />
    <font
        app:font="@font/my_font_light"
        app:fontStyle="normal"
        app:fontWeight="400" />
</font-family>
Run Code Online (Sandbox Code Playgroud)

权重是错误的,400常规的,但我认为如果 Android 只将 400 用于非粗体文本,如果我只是给它期望的值,那么它做一些奇怪的事情的机会就会减少,所以它不必去寻找替代方案(也许选择斜体)。“权重”由我应用到样式的字体系列定义。我没有费心添加粗体,因为样式使用固定的权重,无论如何我都没有使用粗体。

编辑- Jimit Patel 在评论中提到这在一种情况下对他们不起作用,并且使用粗体字体需要指定700的权重以使其在不同的 API 中保持一致。所以也许正确的权重很重要 - 或者在至少选择400700中最接近它的那个。我不能花时间测试所有这些,所以我只是把它放在那里!)


下一个有趣的事情是,如果您通过设置fontFamily属性通过主题将字体系列应用于整个应用程序,这将覆盖fontFamily您通过textAppearance应用程序应用的任何设置,因为主题样式优先于textAppearance. 因此,您的“加权”样式将失去它们的“权重”,因为它们fontFamily会被设置回具有常规 400值的正常版本。

要解决此问题,您必须将样式应用为样式,而不是 textAppearance,即:

style="@style/TextAppearance.MdcTypographyStyles.Headline1"
Run Code Online (Sandbox Code Playgroud)

乐趣!!


Bry*_*yan 5

正如@FlorianWalther指出的那样,该textFontWeight属性正是我所要查找的。该属性显然是在API级别28中添加的,但是直到最近才进行了记录

确保所有权重都在同一个XML文件中(就像在我的问题中一样),然后只需将属性与属性一起使用即可fontFamily

<TextView android:id="@+id/weightedTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="@font/archivo_narrow"
    android:textFontWeight="700"/>
Run Code Online (Sandbox Code Playgroud)

据我所知,此属性仅在以上API级别28中可用,如果在支持库中找到对应的属性,我将进行更新。

  • 与向后移植 `textFontWeight` 相关的问题:https://issuetracker.google.com/issues/145311058 (6认同)
  • 相关问题实际上包含旧版 Android 版本的实现链接。 (3认同)