How do I convert <string-array> into a HashMap - android

It is part of code of a weather application.
I had written following code in strings.xml, but now I want to write in java file. I don't know how to write the following code in HashMap and obtain the value from it.
Following are the string-arrays in my XML.
<!-- Weather condtion 5,6 together with Dress -->
<!-- Weather condtion 11,12 together with Dress -->
<string-array name="eleven">
<item name="dress_6">dress_6</item>
<item name="dress_0">dress_0</item>
<item name="dress_1">dress_1</item>
</string-array>
<!-- Weather condtion 9 together with Dress -->
<string-array name="nine">
<item name="dress_6">dress_6</item>
<item name="dress_4">dress_4</item>
<item name="dress_14">dress_14</item>
</string-array>
<!-- Weather condtion 5,6 together with Dress -->
<string-array name="five">
<item name="dress_2">dress_2</item>
<item name="dress_8">dress_8</item>
<item name="dress_6">dress_6</item>
</string-array>
<!-- condtion 2 -->
<string-array name="two">
<item name="dress_11">dress_11</item>
<item name="dress_5">dress_5</item>
<item name="dress_0">dress_0</item>
</string-array>
<string-array name="twentyFive">
<item name="dress_0">dress_0</item>
<item name="dress_3">dress_3</item>
<item name="dress_8">dress_8</item>
</string-array>
<string-array name="twentySix">
<item name="dress_12">dress_12</item>
<item name="dress_13">dress_13</item>
<item name="dress_5">dress_5</item>
</string-array>
<string-array name="thirtySix">
<item name="dress_11">dress_11</item>
<item name="dress_9">dress_9</item>
<item name="dress_4">dress_4</item>
</string-array>
<string-array name="thirtySeven">
<item name="dress_12">dress_12</item>
<item name="dress_13">dress_13</item>
<item name="dress_3">dress_3</item>
</string-array>

I think you are looking for a way to populate the HashMap
You could use the following
Map<String, List<String>> map = new HashMap<>();
map.put("eleven", Arrays.asList("dress_6", "dress_0", "dress_1"));
if you need a more complex structure you could use something like
Map<String, Map<String, String>> map = new HashMap<>();
To retrieve from the map you could use something like
List<String> list = map.get("eleven");
This list will contain the elements that you added "dress_6", "dress_0", "dress_1"
You can access these elements in a for loop as
for(String item : list) {
System.out.println("Item: " + item);
}
You haven't specified your exact use case but I would recommend not hard coding the configuration. You could read from the existing string.xml file and populate the Map on startup or first access.

Lets try this:
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("name","chris");
map.put("island","faranga");
XStream magicApi = new XStream();
magicApi.registerConverter(new MapEntryConverter());
magicApi.alias("root", Map.class);
String xml = magicApi.toXML(map);
System.out.println("Result of tweaked XStream toXml()");
System.out.println(xml);
Map<String, String> extractedMap = (Map<String, String>) magicApi.fromXML(xml);
assert extractedMap.get("name").equals("chris");
assert extractedMap.get("island").equals("faranga");
}
public static class MapEntryConverter implements Converter {
public boolean canConvert(Class clazz) {
return AbstractMap.class.isAssignableFrom(clazz);
}
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
AbstractMap map = (AbstractMap) value;
for (Object obj : map.entrySet()) {
Map.Entry entry = (Map.Entry) obj;
writer.startNode(entry.getKey().toString());
Object val = entry.getValue();
if ( null != val ) {
writer.setValue(val.toString());
}
writer.endNode();
}
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Map<String, String> map = new HashMap<String, String>();
while(reader.hasMoreChildren()) {
reader.moveDown();
String key = reader.getNodeName(); // nodeName aka element's name
String value = reader.getValue();
map.put(key, value);
reader.moveUp();
}
return map;
}
}
}
Check THIS out for more information.

Related

Getting the value of an item in the array

I have the following items stored in an array-string in String.xml file
<string-array name="cr">
<item name="x"> 20</item>
<item name="y"> 40</item>
<item name="z"> 60</item>
<item name="k"> 80</item>
<item name="i"> 100</item>
<item name="l"> 120</item>
</string-array>
how can i get the value (eg 80) using the item name in mainactivity.java file?
int index =Arrays.asList(getResources().getStringArray(R.array.cr)).indexOf(..); I tried this but it doesn't work
You can use two array(one for key, one for value) and then put them into Hashmap object.
Example:
String[] mobileArray = getResources().getStringArray(R.array.mobile);
String[] priceArray = getResources().getStringArray(R.array.price);
Map<String, String> map = new HashMap<>();
for (int i = 0; i < mobileArray.length; i++) {
map.put(mobileArray[i], priceArray[i]);
}
strings.xml
<string-array name="mobile">
<item>Samsung</item>
<item>Lenevo</item>
<item>Karbon</item>
<item>Moto</item>
<item>Xperia</item>
<item>Micromax</item>
<item>Lava</item>
<item>Xiomi</item>
</string-array>
<string-array name="price">
<item>10000</item>
<item>12000</item>
<item>10000</item>
<item>12000</item>
<item>10000</item>
<item>12000</item>
<item>10000</item>
<item>12000</item>
</string-array>
I think you need something like this
String[] yourArray = getResources().getStringArray(R.array. cr);
String yourString = yourArray[3];
hope this is what you need

NPE on getStringArray

I'm having problems to get an array of colors.
I get a NullPointerException while I fetch the data from the file strings.xml.
The Logcat reports a NPE in this line:
colorList.add(Color.parseColor(colore));
strings.xml
<array name="colors">
<item>#FFFFFF</item>
<item >#FFFFF0</item>
<item >#FFFFE0</item>
<item >#FFFF00</item>
</array>
Adapter
public class ColorPickerAdapter extends BaseAdapter {
private Context context;
private List<Integer> colorList = new ArrayList<Integer>();
public ColorPickerAdapter(Context context) {
this.context = context;
String colors[] = context.getResources().getStringArray(R.array.colors);
colorList = new ArrayList<Integer>();
// add the color array to the list
for(String colore : colors){
colorList.add(Color.parseColor(colore));
}
}
<string-array name="colors">
<item>#FFFFFF</item>
<item>#FFFFF0</item>
<item>#FFFFE0</item>
<item>#FFFF00</item>
</string-array>
use string-array instead of array.

How to get name of arrays

I have this array.xml
<resources>
<string-array name="Abarth">
<item name="id">1</item><item name="title">500</item>
<item name="id">2</item><item name="title">Grande Punto</item>
<item name="id">3</item><item name="title">Punto Evo</item>
<item name="id">4</item><item name="title">500c</item>
<item name="id">5</item><item name="title">695</item>
<item name="id">6</item><item name="title">Punto</item>
</string-array>
<string-array name="Alfa_Romeo">
<item name="id">1</item><item name="title">155</item>
<item name="id">2</item><item name="title">156</item>
<item name="id">3</item><item name="title">159</item>
<item name="id">4</item><item name="title">164</item>
<item name="id">5</item><item name="title">145</item>
<item name="id">6</item><item name="title">147</item>
<item name="id">7</item><item name="title">146</item>
<item name="id">8</item><item name="title">Gtv</item>
<item name="id">9</item><item name="title">Spider</item>
<item name="id">10</item><item name="title">166</item>
<item name="id">11</item><item name="title">Gt</item>
<item name="id">12</item><item name="title">Crosswagon</item>
<item name="id">13</item><item name="title">Brera</item>
<item name="id">14</item><item name="title">90</item>
<item name="id">15</item><item name="title">75</item>
<item name="id">16</item><item name="title">33</item>
<item name="id">17</item><item name="title">Giulietta</item>
<item name="id">18</item><item name="title">Sprint</item>
<item name="id">19</item><item name="title">Mito</item>
</string-array>
<array name="marcas">
<item>#array/Abarth</item>
<item>#array/Alfa_Romeo</item>
</array>
</resources>
I want to get the content of the array marcas and the name of the subarrays, like "Abarth" or "Alfa_Romeo".
How can I do this? In other post I have read the next code, but it is for obtain the entire array, not only a part of the array.
Resources res = getResources();
TypedArray ta = res.obtainTypedArray(R.array.marcas);
int n = ta.length();
String[][] car = new String[n][];
for (int i = 0; i < n; ++i) {
int id = ta.getResourceId(i, 0);
if (id > 0) {
car[i] = res.getStringArray(id);
} else {
// Error en el XML
}
}
Thank you.
I want to get the content of the array marcas and the name of the
subarrays, like "Abarth" or "Alfa_Romeo".
I don't know if i correctly understood your question but to obtain name of arrays you can use this:
TypedArray parent = getResources().obtainTypedArray(R.array.marcas);
List<String> childs = new ArrayList<String>();
for (int i = 0; i < parent.length(); i++) {
int id = parent.getResourceId(i, 0);
if (id > 0) {
childs.add(getResources().getResourceEntryName(id));
}
}
parent.recycle();
Output:
Abarth
Alfa_Romeo
You have done everything well, To get the TypedArray resource name you need to use getResourceEntryName. Add the following code to get the resourceEntryName, to get what you looking for.
getResources().getResourceEntryName(id);
This will give you the output "Abarth" and "Alfa_Romeo".

How to get the "human-readable" part from an values\arrays.xml-file

I just can't figure out how to accomplish the following;
I'd like to display the "human readable form" (refresh_interval_entries), for example in a Log.d(), corresponding to what has been selected in refresh_interval_values.
I have two arrays defined in values\arrays.xml:
<string-array name="refresh_interval_entries" translatable="false">
<item>1 minute</item>
<item>2 minutes</item>
<item>3 minutes</item>
</string-array>
<string-array name="refresh_interval_values" translatable="false">
<item>60</item>
<item>120</item>
<item>180</item>
</string-array>
I save the selected value from refresh_interval_values in a ListPreference.
First I was thinking of doing something like;
String[] mEntries = getResources().getStringArray(R.array.refresh_interval_entries);
But I don't think that will work since I can't get the correct index for mEntries[index], since i can't use the values in refresh_interval_values.
I am not trying to display this in an Activity that extends PreferenceActivity, just in a normal Activity.
Any ideas how to do this?
How about on start of your application, you make a HashMap out of the two arrays:
HashMap<String, String> dictionary = new HashMap<String, String>();
String[] mEntries = getResources().getStringArray(R.array.refresh_interval_entries);
String[] mValues = getResources().getStringArray(R.array.refresh_interval_values);
for (int i = 0; i < mEntries.length; i++) {
dictionary.put(mValues[i], mEntries[i]);
}
and use it like:
String entry = dictionary.get("60");
Do something like this:
{
...
String[] mEntries = getResources().getStringArray(R.array.refresh_interval_entries);
String[] mValues = getResources().getStringArray(R.array.refresh_interval_values);
Log.d(TAG, "120=" + getEntryFromValue("120", mEntries, mValues));
}
private String getEntryFromValue(String value, String[] mEntries, String[] mValues) {
for (int i=0; i < mValues.length; i++) {
if (value.equals(mValues[i])) {
// check mEntries length
return mEntries[i];
}
}
return "NOT FOUND";
}

Search value for key in string-array android

i have a string-array in my res/values/strings.xml
<string-array name="my_list">
<item>Item1</item>
<item>Item2</item>
</string-array>
i am accessing it in my application as and comparing it with my value in loop.
String[] myStrings = getResources().getStringArray(R.array.my_list);
for(int i=0;i<myStrings.length;i++)
{
System.out.println(myStrings[i]);
}
Now i need the search the items according to key to get the respective item.Example
<string-array name="my_list">
<item name="one">Item1</item>
<item name="two">Item2</item>
</string-array>
if my search hay key "one" then get its corresponding value(Item1).
How to accomplish this task.
Thanks
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];
}
Note: The code above will not work if items inside the two lists was unordered. So make sure you arranged the items.
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.
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.
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]);
}
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.
A great way to do this is to make an array of arrays with XML as shown below. Then the native functions make it pretty easy to get the array with the named index you want and get the string inside it.
<string-array name="one">
<item>"Item 1"</item>
</string-array>
<string-array name="two">
<item>"Item 2"</item>
</string-array>
<array name="my_list">
<item>#array/one</item>
<item>#array/two</item>
</array>
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);
You can make resource of your string array like below to show as hashmap kind :
<string-array name="list_websites">
<item>
<string name="title">Amazon</string>
<string name="isChecked">0</string>
</item>
<item>
<string name="title">eBay</string>
<string name="isChecked">0</string>
</item>
<item>
<string name="title">Sam\'s Club</string>
<string name="isChecked">0</string>
</item>
<item>
<string name="title">Wallmart</string>
<string name="isChecked">0</string>
</item>
<item>
<string name="title">Best Buy</string>
<string name="isChecked">0</string>
</item>
<item>
<string name="title">Rekuten</string>
<string name="isChecked">0</string>
</item>
</string-array>
Now above code can be parsed as ArrayList of HashMap kind.

Categories

Resources