从XML资源创建hashmap/map
我正在制作一个应用程序,其中一个web服务从一个web服务(即BEL、FRA、SWE)获取(除其他外)一组代码。在运行期间,我希望将这些代码转换为相应的名称,以显示给用户(即比利时、法国、瑞典)。可能有很多这样的代码,所以我想知道是否有合适的方法将(code,name)条目作为某种映射存储在Android的XML资源中,这样我就可以通过给定的代码快速获取名称了从XML资源创建hashmap/map,xml,android,Xml,Android,我正在制作一个应用程序,其中一个web服务从一个web服务(即BEL、FRA、SWE)获取(除其他外)一组代码。在运行期间,我希望将这些代码转换为相应的名称,以显示给用户(即比利时、法国、瑞典)。可能有很多这样的代码,所以我想知道是否有合适的方法将(code,name)条目作为某种映射存储在Android的XML资源中,这样我就可以通过给定的代码快速获取名称了 这一切都与速度有关,因为地图可以有几百个条目。今天我遇到了同样的问题,学习developer.android.com很长一段时间都没有帮
这一切都与速度有关,因为地图可以有几百个条目。今天我遇到了同样的问题,学习developer.android.com很长一段时间都没有帮助,因为android资源不能是散列(地图),只能是数组 所以我找到了两种方法:
第二个更为敏感,因为您必须同时同步两个数组中的更改和顺序。您还可以用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>
价值1
价值2
价值3
资源分析器:
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;
}
}
公共类ResourceUtils{
公共静态映射getHashMapResource(上下文c,int hashMapResId){
Map=null;
XmlResourceParser=c.getResources().getXml(hashMapResId);
字符串键=null,值=null;
试一试{
int eventType=parser.getEventType();
while(eventType!=XmlPullParser.END_文档){
if(eventType==XmlPullParser.START\u文档){
日志d(“utils”、“启动文件”);
}else if(eventType==XmlPullParser.START_标记){
if(parser.getName().equals(“map”)){
boolean isLinked=parser.getAttributeBoleAnValue(null,“linked”,false);
map=isLinked?新建LinkedHashMap():新建HashMap();
}else if(parser.getName().equals(“条目”)){
key=parser.getAttributeValue(null,“key”);
if(null==键){
parser.close();
返回null;
}
}
}else if(eventType==XmlPullParser.END_标记){
if(parser.getName().equals(“条目”)){
map.put(键、值);
key=null;
值=空;
}
}else if(eventType==XmlPullParser.TEXT){
if(null!=键){
value=parser.getText();
}
}
eventType=parser.next();
}
}捕获(例外e){
e、 printStackTrace();
返回null;
}
返回图;
}
}
我发现弗拉基米尔的建议很有说服力,所以我实施了他的第一个建议:
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;
}
在实施过程中:
SparseArray<String> myStringArray = parseStringArray(R.array.my_string_array);
SparseArray myStringArray=parseStringArray(R.array.my_string_数组);
对你来说可能已经晚了,但对其他感兴趣的人来说可能已经晚了。
如果您的3位国家/地区代码是有效的ISO 3166-1 alpha-3代码
Locale locale = new Locale("", "SWE");
String countryName = locale.getDisplayCountry();
这提供了完整的国家名称和正确的语言。我有一个类似的要求,我以一种比当前解决方案更强大的方式解决了它 首先创建一个资源,该资源是一个国家/地区数组数组:
<array name="countries_array_of_arrays">
<item>@array/es</item>
<item>@array/it</item>
</array>
在这里,我正在将资源加载到2列表
,但是如果需要,您可以使用映射
为什么这个功能更强大?
它允许您使用字符串资源,从而翻译不同语言的国家名称
它允许您将任何类型的资源关联到每个国家,而不仅仅是字符串。例如,您可以将@drawable
与国旗或包含该国家的省/州的
关联
高级示例:
<array name="it">
<item>IT</item>
<item>ITALIA</item>
<item>@drawable/flag_italy</item>
<item>@array/provinces_italy</item>
</array>
您可以通过直接获取字符串[]
而不是类型Darray来简化for循环代码:
String[] countryArray = getResources().getStringArray(id);
countryCodes.add(countryArray[0]);
countryNames.add(countryArray[1]);
关于拥有2个
:
<array name="it">
<item>IT</item>
<item>ITALIA</item>
<item>@drawable/flag_italy</item>
<item>@array/provinces_italy</item>
</array>
最初,我想有2个
(一个代表国家代码,另一个代表国家名称),如另一个答案中所述。但是,使用2
时,您必须确保项目的数量和顺序匹配。有了这个解决方案,你就不需要了。在这方面比较安全。请注意,正如我所说,每个国家/地区数组中项目的顺序很重要:始终将国家/地区代码和国家/地区名称放在相同的顺序中 我认为最安全、最干净的方法还没有发布,所以这是我的$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;
}
}
然后在strings.xml中:
<string name="france">France</string>
...
构建时检查将确保每个国家/地区对每个区域设置都有一个资源,如果将列表作为数组资源维护,则不会有该资源 作为替代方案,您可以将json对象存储在资产中,并使用第二种方法将其解析为MapUse,并通过测试强制执行同步。我实际上更喜欢(至少是原则,因为答案本身相当冗长)。您应该像这样转义管道(“\\\”)字符:“\\\\\”让你的代码正常工作。@limlim你测试过吗?上面的解决方案对我有效,但我很乐意编辑我的帖子。是的,我测试过了。在添加丢失的转义后,它就像一个符咒!您可以在代码中进行转义,从而使XML更干净。也就是说,XML和中的0 | Item1
String[] countryArray = getResources().getStringArray(id);
countryCodes.add(countryArray[0]);
countryNames.add(countryArray[1]);
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;
}
}
<string name="france">France</string>
...
Country country = Country.valueOf(countryCodeFromServer);
context.getResources().getString(country.stringResId);