user754730
user754730

Reputation: 1340

Dynamic ExpandableListView from JSON

I want to fill an ExpandableListView from a JSON file which is parsed.

The goal is to put the first entry (kontakt_titel) as the title of the group and all the others as children...

The JSON file looks like this:

{
"contact":[
  {
     "kontakt_titel":"Berlin",
     "adresse_strasse":"Hauptstrasse 1",
     "adresse_plzort":"4000 Berlin",
     "telefon":"123456789",
     "fax":"123456780",
     "email":"[email protected]",
     "website":"www.berlin.123.com"
  },
  {
     "kontakt_titel":"London",
     "adresse_strasse":"East Highway 1",
     "adresse_plzort":"London",
     "telefon":"123456789",
     "fax":"123456780",
     "email":"[email protected]",
     "website":"www.london.123.com"
  },
  {
     "kontakt_titel":"New York",
     "adresse_strasse":"Time Square 1",
     "adresse_plzort":"12345",
     "telefon":"123456789",
     "fax":"123456780",
     "email":"[email protected]",
     "website":"www.newyork.123.com"
  }
 ]
}

And this is the code where I want to parse those elements into the ExpandableListView:

try {
        JSONArray jContact = json.getJSONArray("contact");
        for (int i = 0; i < jContact.length(); i++) {
            JSONObject c4 = jContact.getJSONObject(i);

            String contact_title = c4.getString("kontakt_titel");
            String adresse_strasse = c4.getString("adresse_strasse");
            String adresse_plzort = c4.getString("adresse_plzort");
            String telefon = c4.getString("telefon");
            String fax = c4.getString("fax");
            String email = c4.getString("email");
            String website = c4.getString("website");

            if (contact_title != null && !contact_title.equals("")) {
                contactTitles.add(contact_title);
            } else {
                contactTitles.add("");
            }
            if (adresse_strasse != null && !adresse_strasse.equals("")) {
                contactAddressStreet.add(adresse_strasse);
            } else {
                contactAddressStreet.add("");
            }
            if (adresse_plzort != null && !adresse_plzort.equals("")) {
                contactAddressPlzOrt.add(adresse_plzort);
            } else {
                contactAddressPlzOrt.add("");
            }
            if (telefon != null && !telefon.equals("")) {
                contactTelephone.add(telefon);
            } else {
                contactTelephone.add("");
            }
            if (fax != null && !fax.equals("")) {
                contactFax.add(fax);
            } else {
                contactFax.add("");
            }
            if (email != null && !email.equals("")) {
                contactEmail.add(email);
            } else {
                contactEmail.add("");
            }
            if (website != null && !website.equals("")) {
                contactWebsite.add(website);
            } else {
                contactWebsite.add("");
            }
        }
    } catch (JSONException e) {
        errorHappened = true;
    } catch (NullPointerException npe) {
        errorHappened = true;
    }

I think this is all working... But I think here is my error somewhere... This is the getChildView() method of my Adapter which extends BaseExpandableListAdapter:

@Override
    public View getChildView(int groupPosition, int childPosition,
            boolean isLastChild, View convertView, ViewGroup parent) {

        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) myContext
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.row_contact, null);
        }

        TextView tvPlayerName = (TextView) convertView
                .findViewById(R.id.tvPlayerName);

        switch (childPosition) {
            case 0:
                tvPlayerName
                        .setText(MainActivity.contactAddressStreet.get(childPosition));
                break;
            case 1:
                tvPlayerName
                        .setText(MainActivity.contactAddressPlzOrt.get(childPosition));
                break;
            case 2:
                tvPlayerName
                        .setText(MainActivity.contactTelephone.get(childPosition));
                break;
            case 3:
                tvPlayerName
                        .setText(MainActivity.contactFax.get(childPosition));
                break;
            case 4:
                tvPlayerName
                        .setText(MainActivity.contactEmail.get(childPosition));
                break;
            case 5:
                tvPlayerName
                        .setText(MainActivity.contactWebsite.get(childPosition));
                break;
            case 6:
                tvPlayerName
                        .setText(MainActivity.contactOpening.get(childPosition));
                break;
        }

        return convertView;
    }

The problem is, that it always takes the same entries for all children in all group. It takes the first entry (Berlin) in all children as first, the second entry of the second one (East Highway 1) in all children as second etc.

Upvotes: 0

Views: 1742

Answers (1)

user
user

Reputation: 87064

The problem is caused by the way you built the data for the ExpandableListView and in the way you tried to show it in the getChildView() method.

You parse that JSON data in lists of equal size where each position in the lists is a piece of the data for one JSON object. In the getChildView method you use the childPosition to get the data for that child from the right list. But using the childPosition is wrong as you'll see the current behaviour.

Group 1(Berlin)

  • childPosition == 0 (use the first position from contactAddressStreet to get the data("Hauptstrasse 1"))
  • childPosition == 1 (use the second position from contactAddressPlzOrt to get the data("London")))

Group 2(London)

  • childPosition == 0 (use the first position from contactAddressStreet to get the data("Hauptstrasse 1"))
  • childPosition == 1 (use the second position from contactAddressPlzOrt to get the data("London")))

As you see, you don't take in consideration the group for which this child is requested and you get the same data no matter what.

To make it work, use the childPosition to use the correct list of data and the groupPosition to get the actual value from the lists:

// ...
case 0: // child 0
     tvPlayerName.setText(MainActivity.contactAddressStreet.get(groupPosition));
     break;
// ...

Another way would be to parse the JSON objects in a data structure more suitable for an ExpandableListView.

Upvotes: 1

Related Questions