Thursday, 19 February 2015

How can I access the @string/... key (instead of value) in XML in Android?



The Goal


In my preferences.xml I would like to store the ID of certain string elements (like) e.g. ...



<string-array name="preference_values">
<item>@string/nav_start</item>
<item>@string/nav_overview</item>
<item>@string/nav_someelse</item>
</string-array>


... meanwhile in xml/pref_general.xml ...



<ListPreference
android:key="@string/preference_key"
android:entryValues="@array/preference_values"
... />


... where the different strings will be localized:



<string name="nav_start">Startbildschirm</string>
<string name="nav_overview">Übersicht</string>
<string name="nav_someelse">Sonstige</string>


Since I don't want to store the localized strings (as these xml definitions do right now), but rather their integer keys, I would really like to know if there is a way of doing this.


This would make the preferences still available after a language change for example.


More Background


I really like being able to access/compare resources in code, which are not subjective to typos or name changes (or at least the IDE checks/handles those for you) e.g.:



switch( getMyPreferenceAsInt(R.string.preferenece_key) ) {

case R.string.nav_start: doSome(); break;
case R.string.nav_someelse: doSomeElse(); break;
...
}


I use something similar for my NavigationDrawer, and find it really nice to work with. This is also where does string values actually come from (it's like a "default start page" preference).



<string-array name="navigation_keys">
<item>@string/nav_start</item>
<item>@string/nav_overview</item>
<item>@string/nav_someelse</item>
...
</string-array>


But at least here I am able to get the keys with obtainTypedArray(...):



void onCreate(Bundle savedInstanceState) {
...
mNavKeys = getResources().obtainTypedArray(R.array.navigation_keys);
}

void onNavigationDrawerItemSelected(int position) {

Fragment fragment;
int selectedResource = mNavKeys.getResourceId(position, R.string.nav_default);

if (selectedResource == R.string.nav_start) {
fragment = FancyStartFragment.newinstance();
}
else {
fragment = ...;
}

// Fancy methods to do a fragment transaction
...
}

No comments:

Post a Comment