我正在创建一个应用程序,其中Web服务从Web服务(即BEL,FRA,SWE)获取(以及其他)一堆代码.在运行期间,我想将这些代码翻译成他们的apporiate名称,以显示给用户(即比利时,法国,瑞典).可能有很多这些代码,所以我想知道是否有任何合适的方式将(代码,名称)条目存储为Android中的XML资源中的某种地图,因此我可以快速获取名称给定的代码?
这都是关于速度的,因为地图可以有几百个条目.
Vla*_*mir 41
今天我遇到了同样的问题并且长时间研究developer.android.com没有帮助,因为Android资源不能是哈希(地图),只有数组.
所以我找到了两种方法:
有一个像"BEL | Belgium"这样的字符串数组,在程序的早期解析这些字符串并存储在Map <>中
有2个字符串数组:首先是"BEL","FRA","SWE"的值,第二个是"Belgium","France","Sweden".
其次是更敏感,因为您必须同时同步两个数组中的更改和顺序.
Jen*_*ohl 41
我发现弗拉基米尔的答案非常引人注目,所以我实施了他的第一个建议:
public SparseArray<String> parseStringArray(int stringArrayResourceId) {
String[] stringArray = getResources().getStringArray(stringArrayResourceId);
SparseArray<String> outputArray = new SparseArray<String>(stringArray.length);
for (String entry : stringArray) {
String[] splitResult = entry.split("\\|", 2);
outputArray.put(Integer.valueOf(splitResult[0]), splitResult[1]);
}
return outputArray;
}
Run Code Online (Sandbox Code Playgroud)
使用它是直截了当的.在你strings.xml你有一个string-array像这样:
<string-array name="my_string_array">
<item>0|Item 1</item>
<item>1|Item 4</item>
<item>2|Item 3</item>
<item>3|Item 42</item>
<item>4|Item 17</item>
</string-array>
Run Code Online (Sandbox Code Playgroud)
并在您的实施中:
SparseArray<String> myStringArray = parseStringArray(R.array.my_string_array);
Run Code Online (Sandbox Code Playgroud)
vok*_*lam 38
您还可以使用XML定义映射,将其放在res/xml中并解析为HashMap(本文中建议).如果要保持键盘顺序解析为LinkedHashMap.简单实现如下:
地图资源res/xml:
<?xml version="1.0" encoding="utf-8"?>
<map linked="true">
<entry key="key1">value1</entry>
<entry key="key2">value2</entry>
<entry key="key3">value3</entry>
</map>
Run Code Online (Sandbox Code Playgroud)
资源解析器:
public class ResourceUtils {
public static Map<String,String> getHashMapResource(Context c, int hashMapResId) {
Map<String,String> map = null;
XmlResourceParser parser = c.getResources().getXml(hashMapResId);
String key = null, value = null;
try {
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_DOCUMENT) {
Log.d("utils","Start document");
} else if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("map")) {
boolean isLinked = parser.getAttributeBooleanValue(null, "linked", false);
map = isLinked ? new LinkedHashMap<String, String>() : new HashMap<String, String>();
} else if (parser.getName().equals("entry")) {
key = parser.getAttributeValue(null, "key");
if (null == key) {
parser.close();
return null;
}
}
} else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("entry")) {
map.put(key, value);
key = null;
value = null;
}
} else if (eventType == XmlPullParser.TEXT) {
if (null != key) {
value = parser.getText();
}
}
eventType = parser.next();
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return map;
}
}
Run Code Online (Sandbox Code Playgroud)
我有类似的要求,我以比当前解决方案更强大的方式解决了它.
首先创建一个国家/地区数组数组:
<array name="countries_array_of_arrays">
<item>@array/es</item>
<item>@array/it</item>
</array>
Run Code Online (Sandbox Code Playgroud)
然后为每个国家添加一个包含国家/地区信息的数组:
<array name="es">
<item>ES</item>
<item>ESPAÑA</item>
</array>
<array name="it">
<item>IT</item>
<item>ITALIA</item>
</array>
Run Code Online (Sandbox Code Playgroud)
一些说明:
name每个国家/地区数组中的值(es,it)必须与中的数组匹配countries_array_of_arrays(如果没有,则会收到错误).
对于所有阵列,每个阵列上的项目顺序必须相同.因此,总是将国家/地区代码放在第一位,将国家/地区名称放在第二位.
每个国家/地区可以包含任意数量的字符串,而不仅仅是国家/地区代码和名称.
要在代码上加载字符串,请执行以下操作:
TypedArray countriesArrayOfArrays = getResources().obtainTypedArray(R.array.countries_array_of_arrays);
int size = countriesArrayOfArrays.length();
List<String> countryCodes = new ArrayList<>(size);
List<String> countryNames = new ArrayList<>(size);
TypedArray countryTypedArray = null;
for (int i = 0; i < size; i++) {
int id = countriesArrayOfArrays.getResourceId(i, -1);
if (id == -1) {
throw new IllegalStateException("R.array.countries_array_of_arrays is not valid");
}
countryTypedArray = getResources().obtainTypedArray(id);
countryCodes.add(countryTypedArray.getString(0));
//noinspection ResourceType
countryNames.add(countryTypedArray.getString(1));
}
if (countryTypedArray != null) {
countryTypedArray.recycle();
}
countriesArrayOfArrays.recycle();
Run Code Online (Sandbox Code Playgroud)
在这里我将资源加载到2,List但Map如果你愿意,你可以使用a .
为什么这更强大?
它允许您使用字符串资源,从而翻译不同语言的国家/地区名称.
它允许您将任何类型的资源关联到每个国家/地区,而不仅仅是字符串.例如,您可以将a @drawable与国家<string-array>/ 地区标志或包含该国家/地区的省/州相关联.
高级示例:
<array name="it">
<item>IT</item>
<item>ITALIA</item>
<item>@drawable/flag_italy</item>
<item>@array/provinces_italy</item>
</array>
Run Code Online (Sandbox Code Playgroud)
请注意,我没有尝试过,但我已经在其他问题中看到了它.例如,在这种情况下,您将使用countryTypedArray.getDrawable(2)获取drawable.
简化:
如果您只使用国家/地区数组的字符串,您可以使用<string-array(而不是<array>)这样的:
<string-array name="it">
<item>IT</item>
<item>ITALIA</item>
</string-array>
Run Code Online (Sandbox Code Playgroud)
您可以通过直接获取String[]而不是以下内容来简化for循环代码TypedArray:
String[] countryArray = getResources().getStringArray(id);
countryCodes.add(countryArray[0]);
countryNames.add(countryArray[1]);
Run Code Online (Sandbox Code Playgroud)
有关2的说明<string-array>:
最初我想到的是<string-array>另一个答案中提到的2 (一个用于国家代码,另一个用于国家名称).但是,使用2时,<string-array>您必须确保项目的数量和顺序匹配.有了这个解决方案,你就不会.在这方面它更安全.请注意,正如我所说,每个国家/地区阵列上的项目顺序很重要:始终将国家/地区代码和国家/地区名称放在同一顺序中!
我认为最安全、最干净的方法还没有发布,所以这是我的 0.02 美元:
如何在代码中创建一个引用字符串资源 id 作为其显示值的枚举类型:
public enum Country {
FRA(R.string.france),
BEL(R.string.belgium),
SWE(R.string.sweden),
...;
@StringRes public int stringResId;
Country(@StringRes id stringResId) {
this.stringResId = stringResId;
}
}
Run Code Online (Sandbox Code Playgroud)
然后在 strings.xml 中:
<string name="france">France</string>
...
Run Code Online (Sandbox Code Playgroud)
当您从网络服务收到商品时:
Country country = Country.valueOf(countryCodeFromServer);
context.getResources().getString(country.stringResId);
Run Code Online (Sandbox Code Playgroud)
构建时检查将确保每个国家/地区都有针对每个区域设置的资源,如果将列表维护为数组资源,则不会拥有该资源。
| 归档时间: |
|
| 查看次数: |
34793 次 |
| 最近记录: |