0

I want to grab the drawable ID from an xml array but using string array, is this possible?

<array name="yoga0">
    <item name="engName">Downward-Facing Dog</item>
    <item name="sanName">Adho mukh a savanasana</item>
    <item name="pic">@drawable/yoga_adho_mukha_svanasana</item>
    <item name="description">foo</item>
    <item name="steps">bar</item>
</array>
<array name="yoga1">
    <item name="engName">Fire Log Pose</item>
    <item name="sanName">Agnistambhasana</item>
    <item name="pic">@drawable/yoga_agnistambhasana</item>
    <item name="description">bar</item>
    <item name="steps">foo</item>
</array>

I want to grab "pic" and put it in a yoga object later. I thought this would suffice (this is just a snippet, the whole code worked before getting only string values):

String[] handle;
handle = res.getStringArray(id); 
String engName = handle[0]; //Access items in your XML array
String sanName = handle[1];
int pic = Integer.parseInt(handle[2]);
String description = handle[3];
String steps = handle[4];

I know the problem is in the snippet because:

java.lang.NumberFormatException: Invalid int: "res/drawable-xhdpi-v4/yoga_adho_mukha_svanasana.png"
                                                                           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                                                                           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                                           at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                                           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                                           at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                           at android.os.Looper.loop(Looper.java:148)
                                                                           at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                           at java.lang.reflect.Method.invoke(Native Method)
                                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

And it takes me straight to the line where I'm trying to parse the String into an Integer. Is there a way that I can do this without making parallel arrays?

EDIT: Full method

private void getYogaArray() {

    Resources res = getResources();
    TypedArray index = res.obtainTypedArray(R.array.yogas); //call the index array
    for (int i = 0; i < index.length(); i++) {
        int id = index.getResourceId(i, 0); //get the index
        if (id != 0) {
            String[] handle;
            handle = res.getStringArray(id); //use the index to get the actual array
            String engName = handle[0]; //Access items in your XML array
            String sanName = handle[1];
            int pic = Integer.parseInt(handle[2]);
            String description = handle[3];
            String steps = handle[4];

            //create object and add to array list
            yogaArrayList.add(i, new Yoga(engName, sanName, pic, description, steps));
        }
    }


}
Stephen
  • 1,072
  • 1
  • 19
  • 33

2 Answers2

1

You should use obtainTypedArray() instead of getStringArray()

Your code should be like this

TypedArray handle = res.obtainTypedArray(id); 
String engName = handle.getString(0); 
String sanName = handle.getString(1);
Drawable pic = handle.getDrawable(2);
String description = handle.getString(3);
String steps = handle.getString(4);

For more function of TypedArray please see the documentation

Niko Adrianus Yuwono
  • 11,012
  • 8
  • 42
  • 64
  • I do use typedarray and your version is giving me errors, can you explain more in depth? I posted an edit of my full method. – Stephen Nov 01 '16 at 01:52
  • Adrianus Yuwon TypedArray =/= res.getStringArray(id); it's giving me a incompatible type error. I changed it to res.obtainTypedArray(id) and I'm getting errors for sanName, pic, des., and steps. It says "It's an expected resource of type styleable..."? – Stephen Nov 01 '16 at 02:04
1

Based on the stack trace it is trying to parse the string value "res/drawable-xhdpi-v4/yoga_adho_mukha_svanasana.png" into an integer which obviously is not an integer. I don't think the Resources class is expanding @drawable/yoga_adho_mukha_svanasana to an ID as you are expecting. It is expanding it to the file path of the resource for the current screen density.

If you are trying to get the resource ID, maybe do this instead. Omit "@drawable/" from your "pic" items. Instead, just put the identifier part like this:

<item name="pic">yoga_agnistambhasana</item>

Then in code, read pic as a String and then concatenate "@drawable/" to it and call Resources.getIdentifier() to convert the name to a resource ID like this:

String pic = handle[2];
int picID = res.getIdentifier("@drawable/" + pic, null, null);

This is a bit of hack. If you are just trying to load the Drawable then you don't really need the ID and Niko's answer looks like it could work. What are you trying to achieve exactly?

Bryan Bedard
  • 2,619
  • 1
  • 23
  • 22
  • Yours seemed to work for me, but I'm getting all 0's for the picID. I'm printing them with Log.d. I'm just trying to fill in a card view with this info right now, but since your code seemed to work it's probably something else I need to work on. – Stephen Nov 01 '16 at 02:38