Android 是不是可以在 XML 文件中定义地图?
Posted
技术标签:
【中文标题】Android 是不是可以在 XML 文件中定义地图?【英文标题】:Android Is it possible to define a map in an XML file?Android 是否可以在 XML 文件中定义地图? 【发布时间】:2012-04-29 01:48:04 【问题描述】:我试图定义一个利用资源的静态哈希表,但由于无法静态访问资源而陷入困境。 然后我意识到定义静态地图最好的地方是在资源文件本身。 如何在 XML 中定义地图? 我相信如果可能的话,它应该类似于 Listpreference 机制,具有条目和条目值。
【问题讨论】:
看看这个..mobiforge.com/developing/story/… 你能给我们举个例子,你到底想做什么? Blehi,我想要一个静态地图,我可以从任何班级多次访问。理想情况下,我希望看起来像这样: 【参考方案1】:您始终可以将 Json 嵌入到您的 strings.xml
文件中:
res/values/strings.xml
<string name="my_map">"F":"FOO","B":"BAR"</string>
在您的 Activity 中,您可以在 onStart
方法中构建您的地图:
private HashMap<String, String> myMap;
@Override
protected void onStart()
super.onStart();
myMap = new Gson().fromJson(getString(R.string.my_map), new TypeToken<HashMap<String, String>>().getType());
此代码需要 Google Gson API 才能工作。您可以使用 android SDK 中的内置 Json API 来完成。
而至于静态访问Map,可以创建静态方法:
private static HashMap<String, String> method(Context context)
HashMap<String, String> myMap = new Gson().fromJson(context.getString(R.string.serve_times), new TypeToken<HashMap<String, String>>().getType());
return myMap;
【讨论】:
这种情况下最好保存为assets文件夹中的json文件!【参考方案2】:上面 CommonsWare 提到了正确的答案,但是由于 XML 解析不是那么简单,为此目的遵循一个简单的解析器:
public static Map<String, String> getHashMapResource(Context context, int hashMapResId)
Map<String, String> map = new HashMap<>();
XmlResourceParser parser = context.getResources().getXml(hashMapResId);
String key = null, value = null;
try
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT)
if (eventType == XmlPullParser.START_TAG)
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;
【讨论】:
正如我写的那样,Commonsware 提到了正确答案,这只是一个补充。我认为在我的答案中再次复制Commonsware的答案没有用【参考方案3】:更简单的选择是使用两个数组。这样做的好处是不再重复 xml 文件,使用更少的代码,并且更直接地使用不同类型的数组。
<string-array name="myvariablename_keys">
<item>key1</item>
<item>key1</item>
</string-array>
<string-array name="myvariablename_values">
<item>value1</item>
<item>value2</item>
</string-array>
那么你的java代码应该是这样的:
String[] keys = this.getResources().getStringArray(R.array.myvariablename_keys);
String[] values = this.getResources().getStringArray(R.array.myvariablename_values);
LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();
for (int i = 0; i < Math.min(keys.length, values.length); ++i)
map.put(keys[i], values[i]);
【讨论】:
这是一个很好的解决方案,在 AOSP 内部用于许多情况。请小心,因为它仅适用于地图小到足以进行编辑而不会导致对齐问题,并且您不会遇到本地化问题的情况。例如,如果您打算只本地化值而不是键,那么如果您需要添加新键,这将成为维护的噩梦。但在很多情况下,这是最好的方法。 @BrentK。这就是为什么你应该总是引用一个字符串资源,而不是一个硬编码的字符串【参考方案4】:如何在 XML 中定义地图?
<thisIsMyMap>
<entry key="foo">bar</entry>
<entry key="goo">baz</entry>
<!-- as many more as your heart desires -->
</thisIsMyMap>
将其放入res/xml/
,并使用getResources().getXml()
加载它。参加活动以建立HashMap<String, String>
。
【讨论】:
这不是我需要的。实际上,它是 XML 中的表格部分。但是我不能在要构建哈希映射的静态上下文中使用 getResources()。 @ilomambo:在自定义Application
子类的 onCreate()
中初始化您的哈希映射。这是在您创建任何ContentProviders
之后调用的,但在您的应用程序的任何其他内容运行之前。 Application
是 Context
,应该可以解析这个 XML。
这个例子不完整。编写 XML 很容易,编写解析器很慢而且很痛苦。请参阅下面的示例以获得更简单的解决方案。
@androiddeveloper:<entry key="foo"><item>bar</item><item>baz</item><item>goo</item></entry>
。或<entry key="foo"><item value="bar"/><item value="baz"/><item value="goo"/></entry>
。或<entry key="foo"><array><item>bar</item><item>baz</item><item>goo</item></array></entry>
。管他呢。 XML 绝对可以处理您在 Java 中选择建模为数组的元素集合。
@androiddeveloper:“Android 的解析器呢?” -- Android 有三个 XML 解析器。所有人都可以解析该 XML。 “我需要将 xml 文件作为参数提供......”——Firebase 应该记录 XML 资源需要的样子。你和我都没有投票决定它应该是什么样子。 Firebase 是否处理数组与 XML 是否处理数组是完全不同的问题。以上是关于Android 是不是可以在 XML 文件中定义地图?的主要内容,如果未能解决你的问题,请参考以下文章