填充 Spinner,将字符串从 Android 中的 XML 映射到数字

发布于 2024-12-12 02:57:20 字数 3945 浏览 0 评论 0原文

在我的应用程序中,我需要具有一组值的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尹雨沫 2024-12-19 02:57:20

我建议你使用第二种方法。本地化方面它很棒,您也得到了想要的结果。

I would suggest you use the second method. Localization wise its great and you're getting the desired result too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文