In the assets
folder of my Android App Project I am storing custom XML files which describe actions in my game. Since they are a little more complex, they can not be directly written as Android Resources.
Update: I am storing my custom (complex) XML files in the res/xml
folder now.
Simple Example:
<dialog>
<npc>1</npc>
<text>Hello! How are you?</text>
</dialog>
What I want is to use the convenient advantages of Android String resources for language localisation. In the example above, I want to save Hello! How are you?
in my res/values/strings.xml
and then reference this somehow like this:
<text>@string/dialog_1_text</text>
I do not want to create different language res/xml
folders where I copy all xml files and translate them completely. I only want parts of it to be translated. Easily by referencing a String resource.
Update 2: I have now found out that the XMLParser that you get from Resource.getXml()
has a method called getAttributeResourceValue()
which converts an attribute like randomAtt="@string/random_string"
automatically to an actual Resource ID.
However, in the XML file, there still is no clear dependency and there is no preview for the string or a warning when you put in an invalid resource. But - since there even is a method for that - I strongly believe that it is possible to let the validator only allow string resources in some custom attributes.
Okay, so after a lot of research in the past two hours, I finally found a very well working solution. I have seen a few threads which ask very similar questions - that's why I am sure this answer might help some programmers in the future.
Requirements:
The requirements for my task were the following: Referencing String Resources in a custom XML file with my own schema, stored in the res/xml
directory. The XML Validator of Android Studio should automatically detect it as a String resource, print a warning when it is invalid - and preview the actual String when it is a valid resource. Also it should be as performant as possible.
Solution:
And this is how I solved it:
Instead of putting the string resource between the tags, I had to put them as an attribute. No big deal in my case.And for the validator to recognize them as String resource, I had to call these attributes
Update: I found out that you can call the attribute whatever you like, and it is not necessary to include the android namespace.text
from the android
namespace:
<main>
<nested>
<test myText="@string/lorem_ipsum_100"/>
</nested>
</main>
(Your custom XML may look as whatever you like/need! This is just an example - it works with unlimited nested tags and your own defined schema.)
I didn't think this was gonna work - but it actually does quite well! Whenever I hit Build project
, it prints out a warning when I used an invalid String resource.
And not only that, it also previews it as desired:
(Note: This screenshot was made before I noticed that you can call the attribute whatever you want/need. There is no need to call it explicitely android:text
. Android Studio will automatically recognize it as a string resource, as long as you put @string/...
.)
Now last but not least, to let your Java code interpret the resource correctly, you have to do this:
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();
}
Performance note: As far as I can see, this solution is also super performant, since android pre-parses the @string/...
automatically into Resource IDs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With