title: Populate Spinner that maps strings to numbers from XML in Android
body: <p>In my application I need to have Spinner with set of values, for example:</p>
  
  <ul>
  <li>today</li>
  <li>tomorrow</li>
  <li>after_tomorrow</li>
  </ul>
  
  <p>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:</p>
  
  <ul>
  <li>Request.TODAY = 0;</li>
  <li>Request.TOMORROW = 1;</li>
  <li>Request.AFTER_TOMORROW = 2;</li>
  </ul>
  
  <p>In UI those value are localized and, more important, could be in different order, depending on locale, for example:</p>
  
  <ul>
  <li>послезавтра (after_tomorrow)</li>
  <li>завтра (tomorrow)</li>
  <li>сегодня (today)</li>
  </ul>
  
  <p><strong>What I want is to have all that stuff in localizable XML</strong> (so localization team will need to edit only XML files, not code):</p>
  
  <ul>
  <li>String values</li>
  <li>String order</li>
  </ul>
  
  <p>I spent some time thinking on that problem, and my solution is here.</p>
  
  <p>In strings.xml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;resources&gt;
      &lt;string name="day_today"&gt;сегодня&lt;/string&gt;
      &lt;string name="day_tomorrow"&gt;завтра&lt;/string&gt;
      &lt;string name="day_after_tomorrow"&gt;послезавтра&lt;/string&gt;
      &lt;array name="day_values"&gt;
          &lt;item&gt;@string/day_after_tomorrow&lt;/item&gt;
          &lt;item&gt;@string/day_tomorrow&lt;/item&gt;
          &lt;item&gt;@string/day_today&lt;/item&gt;
      &lt;/array&gt;
  &lt;/resources&gt;
  </code></pre>
  
  <p>In layout.xml:</p>
  
  <pre><code>            &lt;Spinner
                      android:layout_width="fill_parent"
                      android:layout_height="wrap_content"
                      android:id="@+id/day"
                      android:entries="@array/day_values" /&gt;
  </code></pre>
  
  <p>In MyActivity.java:</p>
  
  <pre><code>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 &gt; 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);
  }
  </code></pre>
  
  <p>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.</p>
  
  <p>I want to hear some opinions on that solution and advises on how it can be implemented in other ways.</p>
  
  <p>Thanks!</p>
  
  <p><strong>Update1:</strong></p>
  
  <p>Another solution uses two string arrays in xml file.</p>
  
  <p>strings.xml:</p>
  
  <pre><code>&lt;string-array name="day_entries"&gt;
      &lt;item&gt;послезавтра&lt;/item&gt;
      &lt;item&gt;завтра&lt;/item&gt;
      &lt;item&gt;сегодня&lt;/item&gt;
  &lt;/string-array&gt;
  &lt;string-array name="day_values"&gt;
      &lt;item&gt;after_tomorrow&lt;/item&gt;
      &lt;item&gt;tomorrow&lt;/item&gt;
      &lt;item&gt;today&lt;/item&gt;
  &lt;/string-array&gt;
  </code></pre>
  
  <p>MyActivity.java:</p>
  
  <pre><code>private static final Map&lt;String, Integer&gt; DAYS;
  
  static {
      DAYS = new HashMap&lt;String, Integer&gt;();
      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);
  }
  </code></pre>
  
  <p>layout.xml:</p>
  
  <pre><code>            &lt;Spinner
                      android:layout_width="fill_parent"
                      android:layout_height="wrap_content"
                      android:id="@+id/day"
                      android:entries="@array/day_entries" /&gt;
  </code></pre>
  
  <p>What do you think about it? Is it better on not than the first one? Maybe other ways to implement such thing?</p>