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&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 是否处理数组是完全不同的问题。

以上是关于Android 是不是可以在 XML 文件中定义地图?的主要内容,如果未能解决你的问题,请参考以下文章

Android 动态创建View,是不是可以使用 style,如何使用?

我可以在Android布局xml文件中定义中间行的文本

Android自定义View

自定义字体和 XML 布局 (Android)

Android XML:设备更改时布局行更改

AndroidManifest.xml文件详解