TypeArray in Android - How to store custom objects in xml and retrieve them?

后端 未结 3 1547
逝去的感伤
逝去的感伤 2020-12-05 10:41

I have a class like

public class CountryVO {
    private String countryCode;
    private String countryName;
    private Drawable countryFlag;

    public St         


        
相关标签:
3条回答
  • 2020-12-05 11:07

    You need to parse the xml before trying to store it in your class. I would recommend that you use the SAX API, you can find a tutorial on it here. Hope this helps!

    0 讨论(0)
  • 2020-12-05 11:23

    When I need custom objects that can be edited outside code i generally use json which is easier to read for both humans and (possibly) machines ;)

    You can also have more complex objects than with simple arrays.

    Once you create a json file (e.g. countries.json) in the /res/raw folder like this:

    { "countries" : [
        {"country" : "Albania", "countryCode" : "al" },
        {"country" : "Algeria", "countryCode" : "dz"},
        {"country" : "American Samoa", "countryCode" : "as"},
        {"country" : "India", "countryCode" : "in"},
        {"country" : "South Africa", "countryCode" : "sa"}
    ]}
    

    you can load the data like this:

    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);
    }
    

    If you don't want to do the parsing manually you can also use gson which helps you to pass the objects and then load the drawables in a lazy fashion... ;)

    Edit: Added utility class

    public String convertStreamToString(InputStream is) { 
      Scanner s = new Scanner(is).useDelimiter("\\A");
      return s.hasNext() ? s.next() : "";
    }
    

    Hope it helps

    0 讨论(0)
  • 2020-12-05 11:29

    Here is example. Read it and look at the methods of TypedArray like get...() for example getDrawable(int index). I would suggest to keep items of the same type in separated arrays.

    <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>
    

    EDIT:

    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;
    }
    
    0 讨论(0)
提交回复
热议问题