填充 Spinner,将字符串从 Android 中的 XML 映射到数字
在我的应用程序中,我需要具有一组值的 Spinner,例如:
- 今天
- 明天
- after_tomorrow
用户选择其中一个,应用程序向服务器发送请求。要发送请求,我需要将用户的选择编码为 int 值:
- Request.TODAY = 0;
- 请求.TOMORROW = 1;
- 请求.AFTER_TOMORROW = 2;
在 UI 中,这些值是本地化的,更重要的是,根据区域设置,可以采用不同的顺序,例如:
- послезавтра (after_tomorrow)
- завтра (tomorrow)
- сегодня (today)
我想要的是将所有这些内容都本地化XML(因此本地化团队只需编辑 XML 文件,而不是代码):
- 字符串值
- 字符串顺序
我花了一些时间思考这个问题,我的解决方案就在这里。
在 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>
在 layout.xml 中:
<Spinner
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/day"
android:entries="@array/day_values" />
在 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);
}
我在该解决方案中只看到一件坏事 - TypedArray.getResourceId() 返回“已解析”id,因此如果涉及某些重定向,则整个“if”将不起作用。
我想听听有关该解决方案的一些意见,以及如何以其他方式实施该解决方案的建议。
谢谢!
更新1:
另一种解决方案在xml文件中使用两个字符串数组。
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" />
您对此有何看法?不比第一个更好吗?也许还有其他方法来实现这样的事情?
In my application I need to have Spinner with set of values, for example:
- today
- tomorrow
- after_tomorrow
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:
- Request.TODAY = 0;
- Request.TOMORROW = 1;
- Request.AFTER_TOMORROW = 2;
In UI those value are localized and, more important, could be in different order, depending on locale, for example:
- послезавтра (after_tomorrow)
- завтра (tomorrow)
- сегодня (today)
What I want is to have all that stuff in localizable XML (so localization team will need to edit only XML files, not code):
- String values
- String order
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我建议你使用第二种方法。本地化方面它很棒,您也得到了想要的结果。
I would suggest you use the second method. Localization wise its great and you're getting the desired result too.