3

I'm writing an Android app that displays a textview dynamically filled in with two lines of a JSON file.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="7dp"
    >
<TextView  
    android:id="@+id/item_name"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:padding="2dp"
    android:textSize="20dp" />
    <TextView  
    android:id="@+id/item_type"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:padding="2dp"
    android:textSize="13dp" />
</LinearLayout>

When any of the list items are clicked, I need to get the rest of that index's JSON array contents and pass that to the next activity as an array to be displayed.

Here's the First Activity Java:

public class TutListActivity extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String sJSON = "";

    if(sJSON == ""){

        InputStream is = this.getResources().openRawResource(R.raw.data);
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String readLine = null;
        StringBuilder sb = new StringBuilder();

        try {

            while ((readLine = br.readLine()) != null) {

            sb.append(readLine);
        }
        sJSON = sb.toString();

        is.close();
        br.close();

        } catch (IOException e) {
            e.printStackTrace();
        }       
    }

    String name = "";
    String type = "";
    String material = "";
    String welding = "";
    String primarybase = "";
    String tipmaterial = "";
    String shape = "";
    String shellcoating = "";

    ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();

    try{
        JSONObject jObject = new JSONObject(sJSON);
        JSONArray  pluginfo = jObject.getJSONArray("parts");

        for(int i=0; i < pluginfo.length(); i++) {
            JSONObject array = pluginfo.getJSONObject(i);

            name = array.getString("name");
            type = array.getString("type");
            material = array.getString("material");
            welding = array.getString("welding");
            primarybase = array.getString("primarybase");
            tipmaterial = array.getString("tipmaterial");
            shape = array.getString("shape");
            shellcoating = array.getString("shellcoating");

            HashMap<String, String> list = new HashMap<String, String>();
            JSONObject e = pluginfo.getJSONObject(i);

            list.put("id",  String.valueOf(i));
            list.put("name", "Plug name: " + e.getString("name"));
            list.put("type", "Type: " +  e.getString("type"));
            mylist.add(list);

            }
        }

    catch(JSONException e){
         Log.e("log_tag", "Error parsing data "+e.toString());
    }

    ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.list_item,
            new String[] { "name", "type" },
            new int[] { R.id.item_name, R.id.item_type });

    setListAdapter(adapter);

    final Intent intent1 = new Intent(getApplicationContext(), TutViewerActivity.class);

    intent1.putExtra("name", name);
    intent1.putExtra("type", type);
    intent1.putExtra("material", material);
    intent1.putExtra("welding", welding);
    intent1.putExtra("primarybase", primarybase);
    intent1.putExtra("tipmaterial", tipmaterial);
    intent1.putExtra("shape", shape);
    intent1.putExtra("shellcoating", shellcoating);

    final ListView lv = getListView();
    lv.setTextFilterEnabled(true);
    lv.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            startActivity(intent1);
        }
    });
}

}

And the second activity Java:

public class TutViewerActivity extends ListActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();

        Bundle extras = getIntent().getExtras();

        String name = extras.getString("name");
        String type = extras.getString("type");
        String material = extras.getString("material");
        String welding = extras.getString("welding");
        String primarybase = extras.getString("primarybase");
        String tipmaterial = extras.getString("tipmaterial");
        String shape = extras.getString("shape");
        String shellcoating = extras.getString("shellcoating");

        TextView itemName = (TextView)findViewById(R.id.item_name);
        TextView itemType = (TextView)findViewById(R.id.item_type);
        TextView itemMaterial = (TextView)findViewById(R.id.item_material);
        TextView itemWelding = (TextView)findViewById(R.id.item_welding);
        TextView itemPrimarybase = (TextView)findViewById(R.id.item_primarybase);
        TextView itemTipmaterial = (TextView)findViewById(R.id.item_tipmaterial);
        TextView itemShape = (TextView)findViewById(R.id.item_shape);
        TextView itemShellcoating = (TextView)findViewById(R.id.item_shellcoating);

        itemName.setText(name);
        itemType.setText(type);
        itemMaterial.setText(material);
        itemWelding.setText(welding);
        itemPrimarybase.setText(primarybase);
        itemTipmaterial.setText(tipmaterial);
        itemShape.setText(shape);
        itemShellcoating.setText(shellcoating);

    }
}

The name and type fields are both filled into the first page. I need to get the rest of the info "material" - "shellcoating" passed on which item I click and pass that as an array to the next Activity.

The logcat error:

11-06 00:42:07.585: E/AndroidRuntime(3122): FATAL EXCEPTION: main
11-06 00:42:07.585: E/AndroidRuntime(3122): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mamlambo.tutorial.tutlist/com.mamlambo.tutorial.tutlist.TutViewerActivity}: java.lang.NullPointerException
11-06 00:42:07.585: E/AndroidRuntime(3122):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at android.app.ActivityThread.access$600(ActivityThread.java:130)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at android.os.Looper.loop(Looper.java:137)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at android.app.ActivityThread.main(ActivityThread.java:4745)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at java.lang.reflect.Method.invokeNative(Native Method)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at java.lang.reflect.Method.invoke(Method.java:511)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at dalvik.system.NativeStart.main(Native Method)
11-06 00:42:07.585: E/AndroidRuntime(3122): Caused by: java.lang.NullPointerException
11-06 00:42:07.585: E/AndroidRuntime(3122):     at com.mamlambo.tutorial.tutlist.TutViewerActivity.onCreate(TutViewerActivity.java:62)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at android.app.Activity.performCreate(Activity.java:5008)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
11-06 00:42:07.585: E/AndroidRuntime(3122):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
11-06 00:42:07.585: E/AndroidRuntime(3122):         ... 11 more

Any thoughts on how to do this easily? Thanks.

  • How are you obtaining this `JSONArray`, when you retrieve the `JSONArray` you could parse at the same time and then pass through `Intent`? – jnthnjns Nov 16 '12 at 13:59
  • @Asok I turn the JSON file I have into a string. Then into a HashMap to fill in the two different textviews based on their ID's using a listAdapter. – Domenik VanBuskirk Nov 16 '12 at 14:11

2 Answers2

2

Instantiate your variables outside of any methods, so long as they wont change values throughout your present Activity without you wanting them too. This allows you to pass Variable values from method to method.

String material;

Here is a simplified version of parsing JSONArray:

for(i=0; i < jArray.length(); i++) {
    JSONObject jObject = jArray.getJSONObject(i);
    material = jObject.getString("material");
}

Using Intent, pass the "material" String shown above into your next activity:

Intent passJSONIntent = new Intent(CurrentActivity.this, NextActivity.class);
passJSONIntent.putExtra("material", material);
startActivity(passJSONIntent);

Retrieve Extra's from Intent in NextActivity's onCreate():

Bundle extras = getIntent().getExtras();
String material = extras.getString("material");
TextView itemType = (TextView)findViewById(R.id.item_type);
itemType.setText(material);

EDIT:

Okay so now all you're missing is setContentView(R.layout.yourLayout);:

public class TutViewerActivity extends ListActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.yourLayout);

        ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();

        Bundle extras = getIntent().getExtras();

        //etc...
jnthnjns
  • 8,962
  • 4
  • 42
  • 65
  • So for this code, would I do `String (field name)` for each part of the array along with the `getString("field name")` and pass each string through the intent method? Or is there a way to get all the info at once? – Domenik VanBuskirk Nov 16 '12 at 14:32
  • Yes, the way I have it structured above you would pass each field name through the `Intent`. You could convert the `JSONArray` to a single `String` and then pass the one `String` into the `NextActivity` and THEN convert the String back to `JSONArray` and parse. http://stackoverflow.com/q/5983932/1134705 – jnthnjns Nov 16 '12 at 14:37
  • I got an error when opening the second activity. It has something to do with `itemType.setText(material);` – Domenik VanBuskirk Nov 16 '12 at 15:30
  • Sounds to me like 'material' is not a `String`. I'd have to see how you're implementing my code example as well as your error to help any further. – jnthnjns Nov 16 '12 at 15:38
  • I updated OP with the java for both activities. If i comment out all the lines of `item____.setText(____);` in the second activity, it runs. Doesn't display any text but the activity opens at least. – Domenik VanBuskirk Nov 16 '12 at 15:51
  • The error you are getting is because, I am assuming here, that your `TextView` is within your `ListView` which means in your `findViewById`'s need to be altered a little to read something like: `TextView itemName = (TextView)myListView.findViewById(R.id.item_name);` – jnthnjns Nov 16 '12 at 16:08
  • However it seems that you're only passing one set of values from the `JSONArray` to the next Activity. I'd pass your `ArrayList` myList with `intent.putStringArrayListExtra("myList", myList);`. I can edit my Answer a little later to reflect, if you'd like. – jnthnjns Nov 16 '12 at 16:14
  • `mylist` is only used to display the name and type in the first activity so I don't need that one passed. My `TextView` is inside of a `LinearLayout` and looks just like the first section of code in the OP, but with the rest of the array displayed for the second activity. – Domenik VanBuskirk Nov 16 '12 at 16:40
  • Updated. Logcat at bottom of OP – Domenik VanBuskirk Nov 16 '12 at 17:09
  • Looks like you're just missing `setContentView()` which tells the system where to look for the `TextView`'s. See edit above. – jnthnjns Nov 16 '12 at 17:16
  • Wow so simple.. But, new problem! This time I know the source of it at least. Whatever item I click, the seond activity displays the stats for the last item. Which means `for(i=0; i < jArray.length(); i++) { JSONObject jObject = jArray.getJSONObject(i); material = jObject.getString("material"); }` is overwriting the previous value for each variable and only passes the last one. After a fix for this it should run properly – Domenik VanBuskirk Nov 16 '12 at 17:25
  • Wonderful, you got it from here? – jnthnjns Nov 16 '12 at 17:30
  • Sort of. I trying to implement the answer to this question into my code.. [link](http://stackoverflow.com/questions/6528088/array-being-overwritten-with-last-index-in-loop) – Domenik VanBuskirk Nov 16 '12 at 17:34
  • I'm just going to use this instead: [link](http://stackoverflow.com/questions/3762887/for-loop-to-populate-array?rq=1) and pass the array depending on the id of the item clicked. Would this worked? – Domenik VanBuskirk Nov 16 '12 at 18:09
  • That would work, but you would need to know which part of the array to reference. You have many options, it's all about preference. You could use a `HashMap` that way you could easily reference the key. Note you can also nest `HashMap`s. Like: `HashMap>`. – jnthnjns Nov 16 '12 at 19:38
-1

Can you put a pseudo-code to explain what do you want?

I dont know if you are looking:

myList.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> a, View v, int position, long id) {


                Intent intent = new Intent(MYCLASS.this, NEXTACTIVITYCLASS.class);
                Bundle b = new Bundle();
                //TRY TO DECODE JSON
                String myJsonString = decodeMYJSON(MYJSON);

                b.putString("JSON",myJsonString);
                intent.putExtras(b); 
                startActivity(intent);

                                          }});
ƒernando Valle
  • 3,634
  • 6
  • 36
  • 58