在自定义 XML 资源中引用字符串资源

Reference String Resource in custom XML Resource

在我的 Android 应用程序项目的 assets 文件夹中,我存储了自定义 XML 文件,这些文件描述了我游戏中的操作。由于比较复杂,不能直接写成Android Resources.

更新: 我现在将自定义(复杂)XML 文件存储在 res/xml 文件夹中。

简单示例:

<dialog>
    <npc>1</npc>
    <text>Hello! How are you?</text>
</dialog>

我想要的是利用Android字符串资源的便利优势进行语言本地化。在上面的示例中,我想将 Hello! How are you? 保存在我的 res/values/strings.xml 中,然后以某种方式引用它:

<text>@string/dialog_1_text</text>

不想创建不同语言的res/xml文件夹,我在其中复制所有xml文件并完全翻译它们。我只想翻译其中的一部分。通过引用字符串资源轻松实现。

更新 2: 我现在发现您从 Resource.getXml() 获得的 XMLParser 有一个名为 getAttributeResourceValue() 的方法,它自动将 randomAtt="@string/random_string" 之类的属性转换为实际的资源 ID。
但是,在 XML 文件中,仍然没有明确的依赖关系,也没有字符串预览或放入无效资源时的警告。但是 - 因为甚至有一种方法 - 我坚信可以让验证器只允许某些自定义属性中的字符串资源。

好的,经过过去两个小时的大量研究,我终于找到了一个非常有效的解决方案。我已经看到一些线程提出了非常相似的问题 - 这就是为什么我确信这个答案将来可能会对一些程序员有所帮助。

要求:
我的任务要求如下:在自定义 XML 文件中使用我自己的模式引用字符串资源,存储在 res/xml 目录中。 Android Studio 的 XML 验证器应自动将其检测为字符串资源,在无效时打印警告 - 并在有效资源时预览实际字符串。此外,它应该尽可能高效。

解法:
这就是我解决它的方法:
我没有将字符串资源 放在标签 之间,而是不得不将它们作为一个属性。对我来说没什么大不了的。
为了让验证器将它们识别为字符串资源,我必须从 android 命名空间调用这些属性 text 更新: 我发现您可以随意调用该属性,并且没有必要包含 android 命名空间。

<main>
    <nested>
        <test myText="@string/lorem_ipsum_100"/>
    </nested>
</main>

(您的自定义 XML 可能看起来像您 like/need 的样子!这只是一个示例 - 它适用于无限嵌套标签和您自己定义的模式。)

我认为这行不通 - 但实际上效果很好!每当我点击 Build project,它会在我使用无效的字符串资源时打印出警告。
不仅如此,它还可以根据需要进行预览:

(注意:此屏幕截图是在我注意到您可以随意调用该属性之前制作的 want/need。无需明确调用它 android:text。Android Studio 将自动识别为字符串资源,只要你输入@string/....)

现在最后但同样重要的是,要让您的 Java 代码正确解释资源,您必须这样做:

XmlResourceParser parser = getResources().getXml(R.xml.tutorial_welcome_dialog);
try {
    while (parser.next() != XmlPullParser.END_DOCUMENT) {
        if (parser.getEventType() == XmlPullParser.START_TAG && parser.getName().equals("test")) {
            String s;
            for (int i = 0; i < parser.getAttributeCount(); i++) {
                if (parser.getAttributeName(i).equals("text"))
                    s = getResources().getString(parser.getAttributeResourceValue(i, -1));
            }
        }

    }
} catch (Exception e) {
    e.printStackTrace();
}

性能说明:据我所知,此解决方案的性能也非常出色,因为 android 会自动将 @string/... 预解析为资源身份证。