【问题标题】:Android Expandable ListView - parsed JSON responseAndroid Expandable ListView - 解析 JSON 响应
【发布时间】:2014-07-14 21:41:55
【问题描述】:

我正在尝试通过为现有 ListView 提供 Expandable ListView 来扩展我的应用程序。我发现的教程/答案通常没有很好的文档记录,也没有检查数据是动态的情况(在我的情况下是来自 API 的解析 JSON 数组响应)。

我有两个数据类:SearchItemInventoryItem。我用 Volley 调用 API,JSON 看起来像这样:

[
  {"product":"foobar", "image_url":"someurl", "inventory_items":
     [
        {"some_attribute":"some_value"},
        {"some_attribute":"some_value"},
        {"some_attribute":"some_value"}
     ]
  },

  {"product.......



  }
]

到目前为止,我只解析了 SearchItems 的 JSON,如下所示:

private void parseJsonFeed(JSONArray response) {
        try {

            for (int i = 0; i < response.length(); i++) {
                JSONObject searchObj = (JSONObject) response.get(i);

                SearchItem searchItem = new SearchItem();
                searchItem.setId(searchObj.getInt("id"));

                searchItem.setProduct(searchObj.getString("product"));

                searchItem.setItemImg(searchObj.getString("img"));

                searchItem.setId(searchObj.getInt("id"));

                searchItem.setUpc(searchObj.getInt("upc"));

                searchItems.add(searchItem);

            }

            // notify data changes to list adapater
            listAdapter.notifyDataSetChanged();
        } catch (JSONException e) {
            e.printStackTrace();
        }
}

现在如何将子 InvetoryItems 添加到适配器中的每个 SearchItem?在解析响应时,我可以遍历每个InventoryItem,但是如何将其添加为相应SearchItem 的子元素?下面是我现有的 BaseAdapter 扩展:

public class SearchItemAdapter extends BaseAdapter {  
    private Activity activity;
    private LayoutInflater inflater;
    private List<SearchItem> searchItems;
    ImageLoader imageLoader = AppController.getInstance().getImageLoader();

    public SearchItemAdapter(Activity activity, List<SearchItem> searchItems) {
        this.activity = activity;
        this.searchItems = searchItems;
    }

    @Override
    public int getCount() {
        return searchItems.size();
    }

    @Override
    public Object getItem(int location) {
        return searchItems.get(location);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (inflater == null)
            inflater = (LayoutInflater) activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (convertView == null)
            convertView = inflater.inflate(R.layout.search_item, null);

        if (imageLoader == null)
            imageLoader = AppController.getInstance().getImageLoader();

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

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

        NetworkImageView itemImg = (NetworkImageView) convertView
                .findViewById(R.id.itemImg);

        SearchItem searchItem = searchItems.get(position);

        // product info
        product.setText(searchItem.getProduct());

        // item pic
        itemImg.setImageUrl(searchItem.getItemImg(), imageLoader);

        upc.setText(String.valueOf(searchItem.getUpc()));

        return convertView;
    }
}

【问题讨论】:

  • 可能是thisthis
  • 谢谢,我喜欢他的教程。不幸的是,本教程实际上只涵盖了一组静态列表项。对我来说,令人困惑的部分不是解析 JSON,而是更多如何解析对象并将对象作为子元素添加到 ListView。有时我希望他能多评论他的代码,以便像我这样的新手能更好地理解它。

标签: android json listview android-listview


【解决方案1】:

第一部分解析-您可以编辑SearchItem 代码以获取和设置List&lt;InventoryItem&gt;,然后在您的解析方法中,您可以遍历jsonArray searchObj.getJsonArray("inventory_item") 创建inventoryItem 对象并将其添加到inventoryList,即您可以稍后添加到searchItem

为 InventoryItem 创建一个单独的 pojo 类,然后编辑 SearchItem

public class SearchItem{
 private List<InventoryItem> inventoryList;
 public void setInventoryList(List<InventoryList> inventoryList)
 {
  this.inventoryList = inventoryList;
 }
 public List<InventoryItem> getInventoryList()
 {
      return this.inventoryList;
 }
 //other object and get/set

}

private void parseJsonFeed(JSONArray response) {
    try {

        for (int i = 0; i < response.length(); i++) {
            JSONObject searchObj = (JSONObject) response.get(i);

            SearchItem searchItem = new SearchItem();
            searchItem.setId(searchObj.getInt("id"));

            searchItem.setProduct(searchObj.getString("product"));

            searchItem.setItemImg(searchObj.getString("img"));

            searchItem.setId(searchObj.getInt("id"));

            searchItem.setUpc(searchObj.getInt("upc"));

            if(searchObj.has("inventory_item")
            {
                  JsonArray array = searchObj.getJsonArray("inventory_item");
                  List<InventoryItem> inList = new ArrayList<InventoryItem>();
                  for(int k=0;k<inList.length();k++)
                     {
                       InventoryItem item = new InventoryItem();
                      item.setSomeAttribute(array.get(k).getString("some_attribute"));
                       inList.add(item);
                     }
              searchItem.setInventoryList(inList);
            }

            searchItems.add(searchItem);

        }

        // notify data changes to list adapater
        listAdapter.notifyDataSetChanged();
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

第二部分:使用ExpandableListAdapter 而不是BaseAdapter。从getChildrenCount()返回searchItems.get(groupPosition).getInventoryList().size()

public class ExpandableListAdapter extends BaseExpandableListAdapter {

private Context _context;
private List<SearchItem> list;

public ExpandableListAdapter(Context context, List<SearchItem> list) {
    this._context = context;
    this.list = list;

}

@Override
public Object getChild(int groupPosition, int childPosititon) {
    return this.list.get(groupPosition).getInventoryList()
            .get(childPosititon);
}

@Override
public long getChildId(int groupPosition, int childPosition) {
    return childPosition;
}

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

    final InventoryItem item = (InventoryItem) getChild(groupPosition, childPosition);

    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this._context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.list_item, null);
    }

    TextView txtListChild = (TextView) convertView
            .findViewById(R.id.lblListItem);

    txtListChild.setText(item.getSomeAttribute());
    return convertView;
}

@Override
public int getChildrenCount(int groupPosition) {
    return this.list.get(groupPosition).getInventoryList()
            .size();
}

@Override
public Object getGroup(int groupPosition) {
    return this.list.get(groupPosition);
}

@Override
public int getGroupCount() {
    return this.list.size();
}

@Override
public long getGroupId(int groupPosition) {
    return groupPosition;
}

@Override
public View getGroupView(int groupPosition, boolean isExpanded,
        View convertView, ViewGroup parent) {
    SearchItem item = (SearchItem) getGroup(groupPosition);
    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this._context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.list_group, null);
    }

    TextView lblListHeader = (TextView) convertView
            .findViewById(R.id.lblListHeader);
    lblListHeader.setTypeface(null, Typeface.BOLD);
    lblListHeader.setText(item.getTitle());

    return convertView;
}

@Override
public boolean hasStableIds() {
    return false;
}

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
    return true;
}
}

【讨论】:

  • 谢谢,这很有帮助。你能扩展问题的第二部分吗?这对我来说是问题的症结所在。
【解决方案2】:

您可以使用库 http://jackson.codehaus.org/ 将所有 json 解析为对象。

要解析您的 json,请尝试使用此代码...响应是您的 JSON。

ObjectMapper mapper = new ObjectMapper();
                        try {

                            List< SearchItem > search = mapper
                                    .readValue(
                                            response,
                                            new TypeReference<List< SearchItem >>() {
                                            });

                            //TODO save your list.

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

还有你的对象 SearchItem

@JsonIgnoreProperties(ignoreUnknown = true)

公共类 SearchItem {

public String product;
public String image_url;
public List<Inventario> inventory_items;


public static class Inventario {
    public String Attribute1;
    public String Attribute2;
}

}

这可以帮助你解析你的 json。

要显示,您需要使用 BaseExpandableListAdapter 安装的 BaseAdapter 的项目。

【讨论】:

  • 谢谢,但我在解析 JSON 时确实没有问题。问题的症结在于如何关联父/子元素并传递给BaseExpandableListAdapter
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多