In my application I need to have Spinner with set of values, for example:
User chooses one of it and applications send request to server. To send the request i need to encode user's choice as int value:
In UI those value are localized and, more important, could be in different order, depending on locale, for example:
What I want is to have all that stuff in localizable XML (so localization team will need to edit only XML files, not code):
I spent some time thinking on that problem, and my solution is here.
In strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="day_today">сегодня</string>
<string name="day_tomorrow">завтра</string>
<string name="day_after_tomorrow">послезавтра</string>
<array name="day_values">
<item>@string/day_after_tomorrow</item>
<item>@string/day_tomorrow</item>
<item>@string/day_today</item>
</array>
</resources>
In layout.xml:
<Spinner
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/day"
android:entries="@array/day_values" />
In MyActivity.java:
private int[] dayMap;
private Spinner uiDay;
private final void setupUI(Bundle savedInstanceState) {
uiDay = (Spinner)findViewById(R.id.day);
final TypedArray dayValues = getResources().obtainTypedArray(R.array.day_values);
dayMap = new int[dayValues.length()];
for (int i = 0; dayMap.length > i; ++i) {
final int r = dayValues.getResourceId(i, 0);
// can't use switch() since resources ids not always final since Android 4
if (R.string.day_today == r) {
dayMap[i] = Request.TODAY;
} else if (R.string.day_tomorrow == r) {
dayMap[i] = Request.TOMORROW;
} else if (R.string.after_tomorrow == r) {
dayMap[i] = Request.AFTER_TOMORROW;
}
}
dayValues.recycle();
}
public void submitClicked(View v) {
final int r = dayMap[uiDay.getSelectedItemPosition()];
submitDayRequest(r);
}
I see only one bad thing in that solution - TypedArray.getResourceId() returns "resolved" id, so if some redirects will be involved entire "if" will not work.
I want to hear some opinions on that solution and advises on how it can be implemented in other ways.
Thanks!
Update1:
Another solution uses two string arrays in xml file.
strings.xml:
<string-array name="day_entries">
<item>послезавтра</item>
<item>завтра</item>
<item>сегодня</item>
</string-array>
<string-array name="day_values">
<item>after_tomorrow</item>
<item>tomorrow</item>
<item>today</item>
</string-array>
MyActivity.java:
private static final Map<String, Integer> DAYS;
static {
DAYS = new HashMap<String, Integer>();
DAYS.put("today", Request.TODAY);
DAYS.put("tomorrow", Request.TOMORROW);
DAYS.put("after_tomorrow", Request.AFTER_TOMORROW);
}
private Spinner uiDay;
private String[] dayValues;
private final void setupUI(Bundle savedInstanceState) {
uiDay = (Spinner)findViewById(R.id.day);
dayValues = getResources().getStringArray(R.array.day_values);
}
public void submitClicked(View v) {
final int r = DAYS.get(dayValues[uiDay.getSelectedItemPosition()]);
submitDayRequest(r);
}
layout.xml:
<Spinner
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/day"
android:entries="@array/day_entries" />
What do you think about it? Is it better on not than the first one? Maybe other ways to implement such thing?
I would suggest you use the second method. Localization wise its great and you're getting the desired result too.
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