Android: Language support, spinner options - android

I have a spinner in my app where the user chooses whether he wants to search by "Contains" "Starts with" "Ends with" or "Equals", The option user selects is stored into a json with other information and sent to server to retrieve results. Now I'm using:
String searchtypeval=searchtype.getSelectedItem().toString();
and adding searchtypeval into my json.
The String-array in the spinner is
<string-array name="search_options">
<item>Starts With</item>
<item>Equals</item>
<item>Ends With</item>
<item>Contains</item>
</string-array>
But now I'm adding language support so in values-fr/strings.xml the string array for that spinner is
<string-array name="search_options">
<item>Commence par </item>
<item>Égal </item>
<item>Se termine par </item>
<item>Contient </item>
</string-array>
Now if the user selects equals in french , Egal is stored into the JSON which of course the server doesn't accept. Is there any way I can make a connection between the french and the english strings.xml? All I can think of now is to use searchtype.getSelectedItemPosition()
and hard code the value into String searchtypeval since I know which option is which position, but this seems very cumbersome, is there any method to solve this issue that is more elegant?

You can send to the server index of a selected element, but this isn't a good way, cause of index is not informated. The better way is sending readable string key to the server. See the following code:
1) create file nontranslatable_string.xml in res/values
<resources>
<string-array name="search_options_keys">
<item>Starts With</item>
<item>Equals</item>
<item>Ends With</item>
<item>Contains</item>
</string-array>
</resources>
2) create your Item class like SpinnerItem
public class SpinnerItem {
public final String key;
public final String value;
private SpinnerItem(String key, String value) {
this.key = key;
this.value = value;
}
public static SpinnerItem create(String key, String value) {
return new SpinnerItem(key, value);
}
#Override
public String toString() {
return value;
}
}
3) fill your adapter with values
String[] keys = context.getResources().getStringArray(R.id.search_options_keys);
String[] values = context.getResources().getStringArray(R.id.search_options);
List<SpinnerItem> items = new ArrayList<SpinnerItem>();
for (int i = 0; i < keys.length; i++) {
items.add(SpinnerItem.create(keys[i], values[i]));
}
spinner.setAdapter(new ArrayAdapter<SpinnerItem>(context, android.R.layout.simple_spinner_item, android.R.id.text1, items));
4) select your value
String valueForSendingToServer = ((SpinnerItem) spinner.getSelectedItem()).key;
UPDATE
Or you can use another way and get neccessary value for any location you use:
Configuration config = context.getResources().getConfiguration();
// Save originla location
Locale originalLocal = config.locale;
// Set new one for single using
config.locale = new Locale("en");
context.getResources().updateConfiguration(config, null);
// Get search_options array for english values
String[] searchOptionsEn = getResources().getStringArray(R.array.search_options);
// Set previous location back
config.locale = originalLocal;
getResources().updateConfiguration(config, null);
String valueForSendingToServer = searchOptionsEn[spinner.getSelectedItemPosition()];

You can reference string resources in the string-array for localization.
<string-array name="search_options">
<item>#string/starts_with</item>
<item>#string/equals</item>
<item>#string/ends_with</item>
</string-array>
and then in res/values/strings.xml:
<string name="starts_with">Starts with </string>
and in res/values-fr/string.xml:
<string name="starts_with">Commence par </string>

Related

Array resource: get name of each item in the array [duplicate]

I have string array that looks like this:
<string-array name="USA">
<item name="NY">001</item>
<item name="LA">002</item>
<item name="WA">003</item>
</string-array>
I can get those numbers by:
Resources res = getResources();
int arryid = res.getIdentifier("USA", "array", getPackageName());
String[] numbers = res.getStringArray(arryid);
But how can I also get the names (NY,LA,WA)?
Note that I have a lot of counties... Maybe use different approach?
In the documentation there is no name attribute for an <item>.
So I don't think there will be any way to get those keys.
However, if you want to get name of string or string-array, you can get it programmatically but not for the <item>.
As "001" is just the index, why not simply use that?
<string-array name="USA">
<item>NY</item>
<item>LA</item>
</string-array>
Then just use index + 1 for the position:
String[] usaStates = getResources().getStringArray(R.array.USA);
int index = 0;
String firstStateName = usaStates[index];
int firstStatePosition = (index + 1);
That aside, you can use two arrays and merge them into a HashMap:
<string-array name="USA">
<item>NY</item>
<item>LA</item>
</string-array>
<string-array name="USA_pos">
<item>001</item>
<item>002</item>
</string-array>
String[] usaStates = getResources().getStringArray(R.array.USA);
String[] usaStatePositions = getResources().getStringArray(R.array.USA_pos);
Map <String, String> map = new HashMap<>(usaStates.length);
for (int i = 0; i < usaStates.length; i++) {
map.put(usaStates[i], usaStatePositions[i]);
}
String[] numbers = getResources().getStringArray(R.array.USA);
to get data from array use.
numbers[id]
add array like this.
<string-array name="USA">
<item>NY</item>
<item>LA</item>
<item>WA</item>
</string-array>

Android : how to create Multidimensional Arrays in string.xml

let's say i have this Multidimensional Array :
myArray = new String[][]{{"Hello","World"},{"I Love","Android"},{"something","Random"}};
and in my app , i'm dealing with it like this :
for (int i=0; i<myArray.length; i++) {
for (int x=0; x<myArray[i].length; x++) {
// set textview or something
}
}
I want to do this Multidimensional Array by XML resource file.
i tried this way but did not work for me :
<string-array name="myArray">
<item><item>Hello</item><item>World</item></item>
<item><item>I Love</item><item>Android</item></item>
<item><item>something</item><item>Random</item></item>
</string-array>
I know I can do normal string-array in the XML file and make it look like Multidimensional Array by Java but I just want to know if it's possible to do it in XML directly
You can maintain your xml for array like this:
<resources>
<array name="categories_0">
<item>1</item>
<item>Pizza</item>
</array>
<array name="categories_1">
<item>2</item>
<item>Burger</item>
</array>
<array name="categories_2">
<item>3</item>
<item>Maggie</item>
</array>
Now each category is an array with a key/value pair for it’s properties. What ties it with other categories is the integer suffix. Now we can use this dandy static method to grab them:
Than, we can define global reference for index of the array:
public class ResourceHelper {
public static List<TypedArray> getMultiTypedArray(Context context, String key) {
List<TypedArray> array = new ArrayList<>();
try {
Class<R.array> res = R.array.class;
Field field;
int counter = 0;
do {
field = res.getField(key + "_" + counter);
array.add(context.getResources().obtainTypedArray(field.getInt(null)));
counter++;
} while (field != null);
} catch (Exception e) {
e.printStackTrace();
} finally {
return array;
}
}
}
This is dynamically retrieving the resources programmatically, with an incremented counter to find the next object until there isn’t one left. Now this can be consumed throughout your code base like this:
for (TypedArray item : ResourceHelper.getMultiTypedArray(this, "categories")) {
Category category = new Category();
category.ID = item.getInt(0, 0);
category.title = item.getString(1);
mCategories.add(category);
}
Here you may face error in encapsulating class or method. You can just add #SuppressWarnings("ResourceType") to that method or class.
This example will work for you.
It's impossible. You can put Json String inside
<item>{"dummy":"dummy"} </item> and then parse it.

Storing String array from other string array

I create on Setting page With Spinner in spinner have a hospital name to select
and when selected hospital in hospital have a phone number to save setting to button clicked call to that hospital
This my String-Array
I have two string - array first is a phone number of hospital
and second is hospital name I need to storing number to hospital name same as line when I selected in spinner
<string-array name ="number">
<item>055270300</item>
<item>055909000</item>
<item>055212222</item>
</string-array>
<string-array name="hospital">
<item>hospital 1</item>
<item>hospital 2</item>
<item>hospital 3</item>
</string-array>
And Here is my Activity:
TextView title = (TextView) findViewById(R.id.toolbar_title);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
title.setText(toolbar.getTitle());
title.setText("การแจ้งเหตุฉุกเฉิน");
phonenum = (EditText)findViewById(R.id.input_phonenum);
message = (EditText)findViewById(R.id.put_message);
preferences = getSharedPreferences(shared_preferences,Context.MODE_PRIVATE);
editor = preferences.edit();
spinner = (Spinner)findViewById(R.id.sos_spinner);
String[] hospital = getResources().getStringArray(R.array.hospital);
ArrayAdapter<String> adapterhospital = new ArrayAdapter<String>(this ,android.R.layout.simple_list_item_1, hospital);
spinner.setAdapter(adapterhospital);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
editor.putInt(String.valueOf(getResources().getStringArray(R.array.number)), R.array.hospital);
editor.commit();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
button = (Button)findViewById(R.id.save_btn);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String getMessage = message.getText().toString();
int getPhonenum = Integer.parseInt(phonenum.toString());
editor.putInt(stored_phonenum, getPhonenum);
editor.putString(stored_message , getMessage);
editor.commit();
Toast.makeText(HowtoActivity.this, "Data Saved.",
Toast.LENGTH_SHORT).show();
}
});
}
I would recommend creating the array using java as opposed to xml.
Its quite simple,
ArrayList<String> hospitals= new ArrayList<>();
then add the hospitals to this array list this way :
hospitals.add("Hospital 1");
hospitals.add("Hospital 2");
hospitals.add("Hospital 3");
Note that this(hospitals array) is the array you will be storing in your spinner.
For the task you want to achieve, this is how i would proceed to do it :
You can have one more arraylist to store both hospital and its respective number seperated by a comma(,):
So create another arrayist, lets call it numbers.
ArrayList<String> numbers = new ArrayList<>();
numbers.add("Hospital 1,71955555");
numbers.add("Hospital 2,71955556");
numbers.add("Hospital 3,71955557");
Now once the user selects an item on the spinner, use the onItemSelected to get the value and store it in shared preferences.
Now just loop through the number arrayList and collect the number if your selected value is equal to the hospital name. You can split the value where the comma is. This way :
for(int i=0;i<numbers.size();i++){
String value = numbers.get(i);
String names[]= value.split(",");
String name = names[0];
if(name.equalsIgnoreCase("Value stored from spinner"){
String number = names[1];
//Store this number in shared preferences as the value for the hospital //selected
}
}
From here you can call the hospital number from your shared preferences in any activity where it is needed.
You can use xml pull Parser for this purpose.
Create an xml like this
<?xml version="1.0" encoding="utf-8"?>
<resources>
<hospital>
<hospital>
<a_name>hospital 1</a_name>
<a_number>71955555</a_number>
</hospital>
<hospital>
<a_name>hospital 1</a_name>
<a_number>71955555</a_number>
</hospital>
<hospital>
<a_name>hospital 1</a_name>
<a_number>71955555</a_number>
</hospital>
<hospital>
<a_name>hospital 1</a_name>
<a_number>71955555</a_number>
</hospital>
</hospitalprovider>

How to use all available string-arrays from all strings.xml?

I am supporting multiple language using values/strings.xml in my app
My current language is ENGLISH.
I have stored icon names in DB, having different languages.
Called following function with icon name in different languages.
More Explanation:[[
Suppose I search "Coffee" then it will return me index =3 because my language is ENGLISH.
Now for next time i search "Kaffee" then it will not found any string like "Kaffee" because my current language is ENGLISH and it is using values/strings.xml file. but i need return index as 3.]]
Need Result : I want to get return index = 3 every time, whatever is my current language.
My thought : Any how I have to search iconName in all of these three languages, not only from current selected ENGLISH language.
Question : So, it is possible to use all supported language's strings to search and get Correct index ?Please give some guidlines!
getIndexOfIcon("Coffee"); --> returns index = 3
getIndexOfIcon("Kaffee"); --> returns index = 0
getIndexOfIcon("Café");--> returns index = 0
public static int getIndexOfIcon(String iconName)
{
String[] predefined_icon_drawable_names;
predefined_icon_drawable_names = mContext.getResources().getStringArray(R.array.predefined_icon_drawable_names_array);
int indextOfIcon = 0;
try
{
indextOfIcon = Arrays.asList(predefined_icon_drawable_names).indexOf(iconName);
if(indextOfIcon<0)
indextOfIcon = 0;
}
catch (Exception e)
{
indextOfIcon = 0;
e.printStackTrace();
}
return indextOfIcon;
}
Following are the strings.xml
ENGLISH Language:/values/strings.xml
<string-array name="predefined_icon_drawable_names_array">
<item>Default</item>
<item>Bath</item>
<item>Brush Teeth</item>
<item>Coffee</item>
</string-array>
GERMAN Language:/values-de/strings.xml
<string-array name="predefined_icon_drawable_names_array">
<item>Standard</item>
<item>Bad</item>
<item>Pinselzähne</item>
<item>Kaffee</item>
</string-array>
SPANISH Language:/values-es/strings.xml
<string-array name="predefined_icon_drawable_names_array">
<item>Por defecto</item>
<item>Baño</item>
<item>Cepillar dientes</item>
<item>Café</item>
</string-array>
Try this way,hope this will help you to solve your problem...
Note : don't try to forget to set your current language after this code.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("English Index : "+getIndexOfIcon(this,"en","Coffee"));
System.out.println("GERMAN Index : "+getIndexOfIcon(this,"de","Kaffee"));
System.out.println("SPANISH Index : "+getIndexOfIcon(this,"es","Café"));
}
public static int getIndexOfIcon(Context mContext,String languageCode,String iconName)
{
Locale locale;
if(languageCode.equals("de")){
locale = new Locale(languageCode,"DE");
}else if(languageCode.equals("es")){
locale = new Locale(languageCode,"ES");
}else{
locale = new Locale(languageCode,"EN");
}
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
mContext.getResources().updateConfiguration(config,mContext.getResources().getDisplayMetrics());
String[] predefined_icon_drawable_names;
predefined_icon_drawable_names = mContext.getResources().getStringArray(R.array.predefined_icon_drawable_names_array);
int indextOfIcon = 0;
try
{
indextOfIcon = Arrays.asList(predefined_icon_drawable_names).indexOf(iconName);
if(indextOfIcon<0)
indextOfIcon = 0;
}
catch (Exception e)
{
indextOfIcon = 0;
e.printStackTrace();
}
return indextOfIcon;
}
I am not quite sure what you want to achieve, but i had a similar problem and solved it with this code:
String localized = context.getResources().getString(context.getResources().getIdentifier(mCursor.getString(COLUMN_NAME), "string", context.getPackageName()));
COLUMN_NAME comes out of a query and i just ID'ed my strings with the same names. You might can use this to get what you need.

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