Referencing a string in a string array resource with xml

AndroidXmlReferencePreferencesArrays

Android Problem Overview


I have preferences where you can enable/disable what items will show up on the menu. There are 17 items. I made a string array in values/arrays.xml with titles for each of these 17 items.

I have preferences.xml which has the layout for my preferences file, and I would like to reference a single item from the string array to use as the title.

How can I do this?

In the Android developer reference, I see how I can reference a single string with XML, but not how I can reference a string from an array resource in XML.

Android Solutions


Solution 1 - Android

In short: I don't think you can, but there seems to be a workaround:.

If you take a look into the Android Resource here:

http://developer.android.com/guide/topics/resources/string-resource.html

You see than under the array section (string array, at least), the "RESOURCE REFERENCE" (as you get from an XML) does not specify a way to address the individual items. You can even try in your XML to use "@array/yourarrayhere". I know that in design time you will get the first item. But that is of no practical use if you want to use, let's say... the second, of course.

HOWEVER, there is a trick you can do. See here:

https://stackoverflow.com/questions/2863827/referencing-an-xml-string-in-an-xml-array-android/2865276#2865276

You can "cheat" (not really) the array definition by addressing independent strings INSIDE the definition of the array. For example, in your strings.xml:

<string name="earth">Earth</string>
<string name="moon">Moon</string>

<string-array name="system">
    <item>@string/earth</item>
    <item>@string/moon</item>
</string-array>

By using this, you can use "@string/earth" and "@string/moon" normally in your "android:text" and "android:title" XML fields, and yet you won't lose the ability to use the array definition for whatever purposes you intended in the first place.

Seems to work here on my Eclipse. Why don't you try and tell us if it works? :-)

Solution 2 - Android

Maybe this would help:

String[] some_array = getResources().getStringArray(R.array.your_string_array)

So you get the array-list as a String[] and then choose any i, some_array[i].

Solution 3 - Android

The better option would be to just use the resource returned array as an array, meaning:

getResources().getStringArray(R.array.your_array)[position]

This is a shortcut approach of other mentioned approaches but does the work in the fashion you want. Otherwise Android doesn't provide direct XML indexing for XML based arrays.

Solution 4 - Android

Unfortunately:

  • It seems you can not reference a single item from an array in values/arrays.xml with XML. Of course you can in Java, but not XML. There's no information on doing so in the Android developer reference, and I could not find any anywhere else.

  • It seems you can't use an array as a key in the preferences layout. Each key has to be a single value with it's own key name.

What I want to accomplish: I want to be able to loop through the 17 preferences, check if the item is checked, and if it is, load the string from the string array for that preference name.

Here's the code I was hoping would complete this task:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());  
ArrayAdapter<String> itemsArrayList = new ArrayAdapter<String>(getBaseContext(),   android.R.layout.simple_list_item_1);  
String[] itemNames = getResources().getStringArray(R.array.itemNames_array);  
  
  
for (int i = 0; i < 16; i++) {  
	if (prefs.getBoolean("itemKey[i]", true)) {  
		itemsArrayList.add(itemNames[i]);  
	}  
} 

What I did:

  • I set a single string for each of the items, and referenced the single strings in the . I use the single string reference for the preferences layout checkbox titles, and the array for my loop.

  • To loop through the preferences, I just named the keys like key1, key2, key3, etc. Since you reference a key with a string, you have the option to "build" the key name at runtime.

Here's the new code:

for (int i = 0; i < 16; i++) {  
    	if (prefs.getBoolean("itemKey" + String.valueOf(i), true)) {  
        itemsArrayList.add(itemNames[i]);  
    }  
}

Solution 5 - Android

Another way of doing it is defining a resources array in strings.xml like below.

<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE resources [
    <!ENTITY supportDefaultSelection "Choose your issue">
    <!ENTITY issueOption1 "Support">
    <!ENTITY issueOption2 "Feedback">
    <!ENTITY issueOption3 "Help">
    ]>

and then defining a string array using the above resources

<string-array name="support_issues_array">
        <item>&supportDefaultSelection;</item>
        <item>&issueOption1;</item>
        <item>&issueOption2;</item>
        <item>&issueOption3;</item>
    </string-array>

You could refer the same string into other xmls too keeping DRY intact. The advantage I see is, with a single value change it would effect all the references in the code.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJorsherView Question on Stackoverflow
Solution 1 - AndroiddavidcesarinoView Answer on Stackoverflow
Solution 2 - Androiduser485498View Answer on Stackoverflow
Solution 3 - AndroidAmiteshView Answer on Stackoverflow
Solution 4 - AndroidJorsherView Answer on Stackoverflow
Solution 5 - AndroidHanuView Answer on Stackoverflow