【问题标题】:Android Is it possible to define a map in an XML file?Android 是否可以在 XML 文件中定义地图?
【发布时间】:2012-04-29 01:48:04
【问题描述】:

我试图定义一个利用资源的静态哈希表,但由于无法静态访问资源而陷入困境。

然后我意识到定义静态地图最好的地方是在资源文件本身。

如何在 XML 中定义地图? 我相信如果可能的话,它应该类似于 Listpreference 机制,具有条目和条目值。

【问题讨论】:

  • 你能给我们举个例子,你到底想做什么?
  • Blehi,我想要一个静态地图,我可以从任何班级多次访问。理想情况下,我希望看起来像这样:

标签: android xml map resources


【解决方案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&lt;String, String&gt;

【讨论】:

  • 这不是我需要的。实际上,它是 XML 中的表格部分。但是我不能在要构建哈希映射的静态上下文中使用 getResources()。
  • @ilomambo:在自定义 Application 子类的 onCreate() 中初始化您的哈希映射。这是在您创建任何ContentProviders 之后调用的,但在您的应用程序的任何其他内容运行之前。 ApplicationContext,应该可以解析这个 XML。
  • 这个例子不完整。编写 XML 很容易,编写解析器很慢而且很痛苦。请参阅下面的示例以获得更简单的解决方案。
  • @androiddeveloper:&lt;entry key="foo"&gt;&lt;item&gt;bar&lt;/item&gt;&lt;item&gt;baz&lt;/item&gt;&lt;item&gt;goo&lt;/item&gt;&lt;/entry&gt;。或&lt;entry key="foo"&gt;&lt;item value="bar"/&gt;&lt;item value="baz"/&gt;&lt;item value="goo"/&gt;&lt;/entry&gt;。或&lt;entry key="foo"&gt;&lt;array&gt;&lt;item&gt;bar&lt;/item&gt;&lt;item&gt;baz&lt;/item&gt;&lt;item&gt;goo&lt;/item&gt;&lt;/array&gt;&lt;/entry&gt;。管他呢。 XML 绝对可以处理您在 Java 中选择建模为数组的元素集合。
  • @androiddeveloper:“Android 的解析器呢?” -- Android 有三个 XML 解析器。所有人都可以解析该 XML。 “我需要将 xml 文件作为参数提供......”——Firebase 应该记录 XML 资源需要的样子。你和我都没有投票决定它应该是什么样子。 Firebase 是否处理数组与 XML 是否处理数组是完全不同的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多