TypeArray en Android-¿Cómo almacenar objetos personalizados en xml y recuperarlos?
custom-component typedarray (3)
Tengo una clase como
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;
}
}
y desea almacenar objetos de esta clase en un XML de TypeArray de Android como
<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>
Cómo quiero acceder a esta matriz en mi clase de Activty como
TypedArray customArr = getResources().obtainTypedArray(R.array.country_arr);
CountryV) 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**);
Pero no sé cómo lograr esto. Intenté customArr.getString (0); pero me da todo como una cuerda como Albania al @ drawable / al
Por favor ayúdame a resolver este problema.
Muchas gracias por adelantado,
Saludos cordiales, Ishan
Cuando necesito objetos personalizados que puedan editarse fuera del código, generalmente uso json, que es más fácil de leer tanto para humanos como (posiblemente) máquinas;)
También puede tener objetos más complejos que con matrices simples.
Una vez que haya creado un archivo json (por ejemplo, countries.json) en la carpeta /res/raw
como este:
{ "countries" : [
{"country" : "Albania", "countryCode" : "al" },
{"country" : "Algeria", "countryCode" : "dz"},
{"country" : "American Samoa", "countryCode" : "as"},
{"country" : "India", "countryCode" : "in"},
{"country" : "South Africa", "countryCode" : "sa"}
]}
Puedes cargar los datos de esta manera:
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);
}
Si no desea realizar el análisis manualmente, también puede usar gson que le ayuda a pasar los objetos y luego cargar los elementos dibujables de forma perezosa ...;)
Edición: Clase de utilidad añadida
public String convertStreamToString(InputStream is) {
Scanner s = new Scanner(is).useDelimiter("//A");
return s.hasNext() ? s.next() : "";
}
Espero eso ayude
Debe analizar el xml antes de intentar almacenarlo en su clase. Le recomendaría que utilice la API de SAX, puede encontrar un tutorial here. ¡Espero que esto ayude!
Aquí está el ejemplo . Léalo y observe los métodos de TypedArray como get...()
por ejemplo, getDrawable(int index)
. Yo sugeriría mantener los elementos del mismo tipo en matrices separadas.
<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>
EDITAR:
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;
}