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

时间:2016-02-26 18:47:44

标签: android xml android-resources

在我的Android App Project的assets文件夹中,我存储了描述游戏中动作的自定义XML文件。由于它们稍微复杂一些,因此无法直接编写为Android资源。

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

简单示例:

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

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

<text>@string/dialog_1_text</text>

想要创建不同的语言res/xml文件夹,我会复制所有xml文件并完全翻译它们。我只想要翻译部分内容。通过引用String资源轻松实现。

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

1 个答案:

答案 0 :(得分:9)

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

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

<强>解决方案:
这就是我解决它的方式:
我不得不将字符串资源放在标签之间,而是将它们作为属性放置。在我的情况下没什么大不了的 为了使验证器将它们识别为String资源,我必须从text命名空间调用这些属性android 更新:我发现您可以随意调用该属性,并且不必包含android命名空间。

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

(您的自定义XML可能看起来像您喜欢/需要的!这只是一个示例 - 它适用于无限制的嵌套标签和您自己定义的架构。)

我认为这不会起作用 - 但实际上它确实很好!每当我点击Build project时,它会在我使用无效的String资源时打印出警告 不仅如此,它还根据需要进行预览: String preview in Android Studio

(注意:此屏幕截图是在我注意到你可以随意调用属性之前制作的。没有必要明确地调用它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/...预先解析为资源ID。