i have a string-array in my res/values/strings.xml
- Item1
- Item2
What you have there is a Map like data structure. Sadly there is currently no way to create a Map of Strings through XML like that.
You could either do it all in Java or write your map in a Raw XML file and read/parse that in to a map at runtime.
XML:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="area_key">
<item>北</item>
<item>中</item>
<item>南</item>
</string-array>
<integer-array name="area_value">
<item>0</item>
<item>1</item>
<item>2</item>
</integer-array>
</resources>
Java file:
String[] areaKey = getResources().getStringArray(R.array.area_key);
int[] areaValue = getResources().getIntArray(R.array.area_value);
HashMap<String, Integer> areas = new HashMap<String, Integer>();
for (int i = 0; i < areaKey.length; i++) {
areas.put(areaKey[i], areaValue[i]);
}
Unfortunately there is no built-in way to achive that, but you can do something like that:
<string-array name="my_array">
<item>key1|value1</item>
<item>key2|value2</item>
</string-array>
And have a util function something like:
Map<String, String> getKeyValueFromStringArray(Context ctx) {
String[] array = ctx.getResources().getStringArray(R.array.my_array);
Map<String, String> result = new HashMap<>();
for (String str : array) {
String[] splittedItem = str.split("|");
result.put(splittedItem[0], splittedItem[1])
}
return result
}
It's look a little bit hacky, but in general, because you have control over your dictionary - probably it not so awful idea.
I had the same problem. The decision for me was to create many strings in xml-file (not string arrays) and to create String[] array in code. It looks like this:
Builder builder = new AlertDialog.Builder(DMCBrowser.this);
builder.setTitle(R.string.title_playlist);
final CharSequence[] items = new CharSequence[] { getResources().getString(R.string.watch_all),
getResources().getString(R.string.select_items) };
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (items[which].equals(getResources().getString(R.string.watch_all))) {
Log.d(TAG, "Watch all");
} else if (items[which].equals(getResources().getString(R.string.select_items))) {
Log.d(TAG, "Select items");
}
}
}).show();
Although it does not look much compact, we can differ one item from another not only by non-understandable identifier like 1 or 2, but by human-readable android R-id. If i would like to change item order, it will be very easy.
you can use in java code:
public static HashMap<Integer, String> getAll()
{
HashMap<Integer, String> items = new HashMap<Integer, String>();
items.put(0, "item 1");
items.put(1, "item 2");
items.put(2, "item 3");
return items;
}
public static Integer getKey(Map hm, String value) {
for (Object o : hm.keySet()) {
if (hm.get(o).equals(value)) {
return (Integer)o;
}
}
return 0;
}
and bind to spinner:
Spinner spn_items = (Spinner) view.findViewById(R.id.spn_items);
ArrayAdapter<Object> adapter = new ArrayAdapter<Object>(getActivity(),android.R.layout.simple_spinner_dropdown_item, getAll().values().toArray()); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spn_items.setAdapter(adapter);
Well, I've done it using two arrays. Easy to manage as well.
One for Keys:
<string-array name="codes">
<item>AC</item>
<item>AD</item>
<item>AE</item>
</string-array>
One for Values:
<string-array name="names">
<item>Ascension</item>
<item>Andorra</item>
<item>United Arab Emirates</item>
</string-array>
And the search method.
private String getCountryByCode(String code) {
int i = -1;
for (String cc: getResources().getStringArray(R.array.codes)) {
i++;
if (cc.equals(code))
break;
}
return getResources().getStringArray(R.array.names)[i];
}