Android 中的 TypeArray - 如何在 xml 中存储自定义对象并检索它们?
Posted
技术标签:
【中文标题】Android 中的 TypeArray - 如何在 xml 中存储自定义对象并检索它们?【英文标题】:TypeArray in Android - How to store custom objects in xml and retrieve them? 【发布时间】:2011-10-10 02:46:01 【问题描述】:我有一门课
public class CountryVO
private String countryCode;
private String countryName;
private Drawable countryFlag;
public String getCountryCode()
return countryCode;
public void setCountryCode(String countryCode)
this.countryCode = countryCode;
public String getCountryName()
return countryName;
public void setCountryName(String countryName)
this.countryName = countryName;
public Drawable getCountryFlag()
return countryFlag;
public void setCountryFlag(Drawable countryFlag)
this.countryFlag = countryFlag;
并希望将此类的对象存储在类似 android 的 TypeArray xml 中
<resources>
<array name="custom_arr">
<item>
<countryName>Albania</countryName>
<countryCode>al</countryCode>
<countryFlag>@drawable/al</countryFlag>
</item>
<item>
<countryName>Algeria</countryName>
<countryCode>dz</countryCode>
<countryFlag>@drawable/dz</countryFlag>
</item>
<item>
<countryName>American Samoa</countryName>
<countryCode>as</countryCode>
<countryFlag>@drawable/as</countryFlag>
</item>
<item>
<countryName>India</countryName>
<countryCode>in</countryCode>
<countryFlag>@drawable/in</countryFlag>
</item>
<item>
<countryName>South Africa</countryName>
<countryCode>sa</countryCode>
<countryFlag>@drawable/sa</countryFlag>
</item>
</array>
</resources>
我想如何在我的 Activty 类中访问这个数组,比如
TypedArray customArr = getResources().obtainTypedArray(R.array.country_arr);
CountryVO vo = new CountryVO();
vo.setCountryName(**value from array come here for first element's countryName attribute**);
vo.setCountryCode(**value from array come here for first element's countryCode attribute**);
vo.setCountryFlag(**value from array come here for first element's countryFlag attribute**);
但我不知道如何实现这一点。 我试过 customArr.getString(0);但它给了我一切都像字符串一样 阿尔巴尼亚 al @drawable/al
请帮我解决这个问题。
非常感谢,
谨此致以最诚挚的问候, 伊山
【问题讨论】:
【参考方案1】:Here is example。阅读并查看 TypedArray 的方法,例如 get...()
,例如 getDrawable(int index)
。我建议将相同类型的项目保留在单独的数组中。
<array name="country">
<item>Albania</item>
<item>Algeria</item>
<item>American Samoa</item>
</array>
<array name="code">
<item>al</item>
<item>dz</item>
<item>as</item>
</array>
<array name="flag">
<item>@drawable/dz</item>
<item>@drawable/al</item>
<item>@drawable/as</item>
</array>
编辑:
public CountryVO getCountryVO(int index)
Resources resources = getResources();
TypedArray country = resources.obtainTypedArray(R.array.country);
TypedArray code = resources.obtainTypedArray(R.array.code);
TypedArray flag = resources.obtainTypedArray(R.array.flag);
CountryVO vo = new CountryVO(country.getString(index), code.getString(index), flag.getDrawable(index));
country.recycle();
code.recycle();
flag.recycle();
return vo;
【讨论】:
感谢 Dziobas 的重播。实际上我这样做并创建了三个不同的数组,但它似乎是有线的,所以我只是想找到一种方法,我可以将所有数据存储在单个 xml 中。而不是 getDrawable(int index) 我想做一些类似 getCountryVO(int index) 的事情有没有办法实现这一点? 您可以在getCountryVO(int index)
中实现它,只需在里面输入代码即可从数组中获取国家、代码和标志。
但是在 getResources().obtainTypedArray("array_name") 的时候,它不可能做 getResources().obtainTypedArray("array_name").getCountryVO(index)。那么请您指导我如何从 TypedArray 获取特定索引处的特定对象?
您好,谢谢!这是您在新 CountryVO 中提供的一个很好的解决方案。但是你知道这有两个缺点,如果我错了,请纠正我。 1.我们需要管理3个不同的xml,难度大且容易出错。 2. 在 CountryVO 中获取所有这 3 个数组以仅创建一个对象,从内存管理的角度来看,这似乎很奇怪。这就是为什么我想在一个数组中管理所有这些信息。目前我选择其他解决方案,即在 Map 上创建并将我所有的 CountryVO 放入其中。
我刚刚回答了你的问题。正如我提供的链接一样,它位于一个 xml 文件中。我不确定,但是资源中的 xmls 是在应用程序二进制文件中构建的,因此它可能会被编译器优化。它应该比在 SAX 中解析更快。当然你也可以把它放在java类的静态数组中。不知道你有什么要求。祝你好运。【参考方案2】:
当我需要可以在代码之外编辑的自定义对象时,我通常使用 json,这对于人类和(可能)机器来说都更容易阅读;)
您还可以拥有比简单数组更复杂的对象。
在/res/raw
文件夹中创建一个 json 文件(例如 countries.json)后,如下所示:
"countries" : [
"country" : "Albania", "countryCode" : "al" ,
"country" : "Algeria", "countryCode" : "dz",
"country" : "American Samoa", "countryCode" : "as",
"country" : "India", "countryCode" : "in",
"country" : "South Africa", "countryCode" : "sa"
]
你可以像这样加载数据:
InputStream jsonStream = context.getResources().openRawResource(R.raw.countries);
JSONObject jsonObject = new JSONObject(Strings.convertStreamToString(jsonStream));
JSONArray jsonContries = jsonObject.getJSONArray("countries");
List<CountryVO> countries = new ArrayList<CountryVO>();
for (int i = 0, m = countries.length(); i < m; i++)
JSONObject jsonCountry = countries.getJSONObject(i);
CountryVO country = new CountryVO();
country.setCountryName(jsonCountry.getString("country"));
String co = jsonCountry.getString("countryCode");
country.setCountryCode(co);
try
Class<?> drawableClass = com.example.R.drawable.class; // replace package
Field drawableField = drawableClass.getField(co);
int drawableId = (Integer)drawableField.get(null);
Drawable drawable = getResources().getDrawable(drawableId);
country.setCountryFlag(drawable);
catch (Exception e)
// report exception
countries.add(country);
如果您不想手动进行解析,您也可以使用gson,它可以帮助您传递对象,然后以惰性方式加载可绘制对象... ;)
编辑:添加实用程序类
public String convertStreamToString(InputStream is)
Scanner s = new Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
希望对你有帮助
【讨论】:
我收到一个错误cannot resolve method convertStreamToString
。我尝试导入所有可用选项
非常正确。我忘了。这是一个实用程序类。我会尝试找到代码。尽管功能是将流的输出复制到一个新字符串中,但还是有解决方案的。
另外,如果你可以使用 Gson,我会推荐它。更少的低级代码
是的,我最终以其他方式进行了操作。谢谢:)【参考方案3】:
您需要先解析 xml,然后再尝试将其存储在您的类中。我建议你使用 SAX API,你可以找到一个关于它的教程here.希望这会有所帮助!
【讨论】:
嗨,Kenny,谢谢你的回复,但我们不能用 android xml 和 getResources().obtailtypearray() 来解决这个问题吗?显式 xml 解析会增加我的应用程序的头痛。以上是关于Android 中的 TypeArray - 如何在 xml 中存储自定义对象并检索它们?的主要内容,如果未能解决你的问题,请参考以下文章
从Objective C中的NSArray转换时如何比较String?