“如何修复 Android Q 中的‘java.lang.IllegalArgumentException: Font has been added’错误?”

Hin*_*dia 16 android

我必须尝试 Android Q 中的新功能(Android Q 和 AppCompat v1.1.0 中默认情况下断字是关闭的),我也阅读了该文档。当我按照 Android 博客中的说明操作时,它工作正常,但是当我尝试按照文档操作时,我发现了错误。

我只使用一个单一的字体系列。下面的代码正在运行:

tvTest.typeface = Typeface.CustomFallbackBuilder(
            FontFamily.Builder(
                Font.Builder(resources.assets, "aguafina_script.ttf").build()).build())
        .addCustomFallback(FontFamily.Builder(
                Font.Builder(resources.assets, "Font_Solid_900.otf").build()).build())
        .build()
Run Code Online (Sandbox Code Playgroud)

但是当我尝试添加多个字体系列时,我遇到了错误。

  Font regularFont = new Font.Builder("regular.ttf").build();
  Font boldFont = new Font.Builder("bold.ttf").build();
  FontFamily family = new FontFamily.Builder(regularFont)
      .addFont(boldFont).build();
  Typeface typeface = new Typeface.CustomFallbackBuilder(family)
      .setWeight(Font.FONT_WEIGHT_BOLD)  // Set bold style as the default style.
                                         // If the font family doesn't have bold style font,
                                         // system will select the closest font.
      .build();
Run Code Online (Sandbox Code Playgroud)

以上代码在文档 https://developer.android.com/reference/kotlin/android/graphics/Typeface.CustomFallbackBuilder.html 中给出

那么你能帮我解决这个错误吗?

Dav*_*eds 29

当您尝试将具有相同样式和粗细的多个字体注册到同一字体系列中时,此错误出现在 androidx.core(或 core-ktx)版本 1.2.0 及更高版本的 Android 10 中。

尽管您的示例以编程方式创建字体系列,但大多数开发人员在使用字体 XML 时都会遇到此错误,因此让我们从这个开始。

在字体 XML 中,我们不能有多个font具有相同fontStylefontWeight属性的元素。例如,以下 XML 会导致此错误,因为两个font元素的样式和权重值相同:

<?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/gibson_regular"
        android:fontStyle="normal"
        android:fontWeight="400" />
    <font
        android:font="@font/gibson_bold"
        android:fontStyle="normal"
        android:fontWeight="400" />
</font-family>
Run Code Online (Sandbox Code Playgroud)

即使 的值font不同(@font/gibson_regularvs @font/gibson_bold),fontStylefontWeight是相同的,所以这会导致错误。

另外,请注意,如果您不提供fontStylefontWeight属性,它们分别默认为normal400,因此下一个示例也会失败:

<?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/gibson_regular"
        android:fontStyle="normal"
        android:fontWeight="400" />
    <font
        android:font="@font/gibson_bold" />
</font-family>
Run Code Online (Sandbox Code Playgroud)

要解决此问题,请确保每个元素的和组合是唯一的。例如,如果我们正确设置了字体,我们将避免错误:fontStylefontWeightfontfontWeightgibson_bold

<?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/gibson_regular"
        android:fontStyle="normal"
        android:fontWeight="400" />
    <font
        android:font="@font/gibson_bold"
        android:fontStyle="normal"
        android:fontWeight="700" />
</font-family>
Run Code Online (Sandbox Code Playgroud)

现在,当以编程方式构建它时,如上所示,适用相同的规则。看起来您引用的 API 文档尚未更新以匹配源代码实际执行的操作。您的示例现在应该如下所示:

val regularFont: Font = Font.Builder(resources.assets,"regular.ttf").build()
val boldFont: Font = Font.Builder(resources.assets, "bold.ttf").build()
val family: FontFamily = FontFamily.Builder(regularFont).addFont(boldFont).build()

val typeface: Typeface = CustomFallbackBuilder(family)
    .setStyle(FontStyle(FONT_WEIGHT_BOLD, FONT_SLANT_UPRIGHT))
    .build()
Run Code Online (Sandbox Code Playgroud)

当写它编程这个样子,看来Android的正确注意到字体的粗细和样式在通过加载它们的时候Font.Builder,所以只要regular.ttfbold.ttf他们的体重和风格不同,该代码将正常工作。

但是如果两种字体具有相同的粗细和样式,或者如果您手动指定字体和样式相同,例如您要调用setWeight(400)粗体字体,您仍然会遇到此异常。

总之,在使用字体 XML 时,始终为每种字体指定fontStylefontWeight。并且无论您是使用 XML 编写内容还是以编程方式构建它们,都要确保字体系列中每种字体的粗细和样式的组合是唯一的。


Ore*_*Ore 10

免责声明:我的情况和你的不一样,但错误是一样的。我只想帮助遇到这个问题的人,因为这是唯一提到错误的人。也许它也有助于OP。

事实证明,罪魁祸首是我的 font-family xml 文件。尽管我的文件在 Android 9 及更低版本上运行良好,但在 Android 10(Q) 上却失败了。原因是我将多个 fontStyles 定义为“正常”:

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

    <font
        app:fontStyle="normal"
        app:font="@font/dosis_regular"/>

    <font
        app:fontStyle="normal"
        app:font="@font/dosis_bold"/>

    <font
        app:fontStyle="normal"
        app:font="@font/dosis_light"/>

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

在我将其更改为只有其中一个是“正常的”之后,它工作得很好。

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

    <font
        app:fontStyle="normal"
        app:font="@font/dosis_regular"/>

    <font
        app:fontWeight="700"
        app:font="@font/dosis_bold"/>

    <font
        app:fontStyle="italic"
        app:font="@font/dosis_light"/>

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