2

I am trying to create a custom Adapter from JSON Data, I can create a ListView with all the data packed in one row per record but I want each value to be in it's on row. Sample JSON

{
"outages": [
    {
            "outagnumber": "567273",
            "impact": "half a block",
            "status": "almost complete",
            "timestamp": "07-19-2015 12:00:00am"               
    },
    {
            "outagnumber": "567243",
            "impact": "whole block",
            "status": "whating on crew",
            "timestamp": "07-19-2015 11:00:00am"
    },


           ]
}

What is the best way of achieving this?

Adapter

public class CustomListOutageAdapter extends ArrayAdapter{

private final Activity context;
private final LinkedList<HashMap<String, String>> itemname;


public CustomListOutageAdapter(Activity context, LinkedList<HashMap<String, String>> itemname) {
    super(context, R.layout.mylistoutagedetails, itemname);
    // TODO Auto-generated constructor stub

    this.context = context;
}

public View getView(int position, View view, ViewGroup parent) {
    LayoutInflater inflater = context.getLayoutInflater();
    View rowView = inflater.inflate(R.layout.mylistoutagedetails, null, true);

    TextView txtTitle = (TextView) rowView.findViewById(R.id.name);


    txtTitle.setText(itemname.get(position).toString());
    return rowView;

};
}
6
  • Are you saying you want this: "outagnumber": "567273" in its own list, and this: "impact": "half a block" in its own list, and do this for each json object in your array? Sorry I'm not understanding what you're trying to achieve Commented Jul 20, 2015 at 14:55
  • @TooManyEduardos Yes each in it's on row in the list. Commented Jul 20, 2015 at 14:59
  • But what's your question though? Are you asking how to parse the json or are you asking how to make the UI for a list view? Commented Jul 20, 2015 at 15:02
  • @TooManyEduardos My JSON is already parsed, I'm trying to show the data inside a listview With each "outagnumber": "567273" etc.. with it's on row. What I currently have is the whole block of data for each outage in each row. So instead of just having two rows I should have 8 rows of data. Commented Jul 20, 2015 at 15:16
  • what is this returning? itemname.get(position).toString() Commented Jul 20, 2015 at 16:52

2 Answers 2

2

I get a feeling you need some help understanding adapters, so let's start from scratch. Hopefully this helps you.

The issue you have is that a adapter is a just a single "cell", and the adapter will create x number of cells.

An adapter requires a list (arraylist, list, linkedlist...) and uses each element in the list as the content for the cell, and by default, the number of cells it will generate. You can override the getCount() method to dictate a different number of cells you may want. (you can even do something like someList.size() + 4, or whatever else you want to add to the number of cells)

So, if you want to display those 8 elements in their own cells, you have a few options:

  • In the activity (not the adapter) you can create a new List (arrayList would probably be easier) with each element of the json. This make it so you pass 1 list with all the objects already separated individually. This is usually a bad practice and a bad idea, but since you want to display it in this odd way anyways, this might be quickest way.

  • Again in the activity you can create an object called "outages" which contains the elements in the "outages" tag (outagnumber, impact...), then you add those objects to a new list, and pass this new list to the adapter. The adapter will then have a list with 2 objects (in this example) and then you can create 2 cells with 4 textview elements each, and add each element of each object to each textview. This is probably the best way to do it, but each element won't be in its own cell.

  • You can go with the viewHolder approach suggested by @nolleh, although it will over complicate this issue since you're now using Recycler views.

Let me know if this helps.

Edit: Added example

Here's an example of how you can do it with an adapter for 2 cells, each cell including the text you want:

Activity class

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

        // Please don't create objects like this. This is just an example
        Outages outagesObject = new Outages();
        outagesObject.outagnumber = jsonValue;
        outagesObject.impact = jsonValue;
        outagesObject.status = jsonValue;
        outagesObject.timestamp = jsonValue;

        List<Outages> listOfOutagesObjects = new ArrayList<Outages>();
        listOfOutagesObjects.add(outagesObject);
        listOfOutagesObjects.add(outagesObject2);

        OutagesAdapter adapter = new OutagesAdapter(listOfOutagesObjects);
        setListAdapter(adapter);
    }
}

Adapter class

public class OutagesAdapter extends ArrayAdapter<Outages>
{
    private List<Outages> listOfOutagesObjects;

    public InitialGetDataActivityAdapter(List<Outages> listOfOutagesObjects)
    {
        super(context, R.layout.single_row, listOfOutagesObjects);
        this.listOfOutagesObjects = listOfOutagesObjects;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        Outages outagesObject = listOfParseObjects.get(position);
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View rowView = inflater.inflate(R.layout.single_row, parent, false);

        TextView tv_outagnumber = (TextView) rowView.findViewById(R.id.tv_outagnumber);
        TextView tv_impact = (TextView) rowView.findViewById(R.id.tv_impact);
        TextView tv_status = (TextView) rowView.findViewById(R.id.tv_status);
        TextView tv_timestamp = (TextView) rowView.findViewById(R.id.tv_timestamp);

        tv_outagnumber.setText(outagesObject.outagnumber);
        tv_impact.setText(outagesObject.impact);
        tv_status.setText(outagesObject.status);
        tv_timestamp.setText(outagesObject.timestamp);

        return rowView;
    }
}

And you need to make your layout file (R.layout.single_row) with each textview you want in whatever layout order you want.

Sign up to request clarification or add additional context in comments.

4 Comments

your right didn't understand adapters, the second option would be best. Can you provide an example? Thanks
I just added an example of activity + adapter.
It this answers your question, please mark it as answered so it can help other people in the future
Thanks man, This worked and helped me understand the way adapters work.
1

how about change items as JSONArray ? and I am not familier with your ArrayAdapter, changed as BaseAdapter.

the code would be like below .. there are some idiom like viewHolder, it is just keeps its' views, for convenient access.

import org.json.JSONArray;
public class CustomListOutageAdapter extends BaseAdapter{

private final Activity mContext;
private final JSONArray mData;
/// items is 
public CustomListOutageAdapter(Activity context, JSONArray items) {
    //super(context, R.layout.mylistoutagedetails, itemname);
    this.mContext = context;
    this.mData = items; 
}

public View getView(int position, View view, ViewGroup parent) {
    ViewHolder vh;
    if (view == null) {
        LayoutInflater inflater = context.getLayoutInflater();
        view = inflater.inflate(R.layout.mylistoutagedetails, null, true);
        vh = new ViewHolder();
        vh.txtName = (TextView) view.findViewById(R.id.name);
        view.setTag(vh);
    }
    else {
        vh = (ViewHolder) view.getTag();
    } 

    if (mData.size() > position) { 
        vh.txtTitle.setText(mData.get(position).toString());
    }
    return view;
}

public class ViewHolder {
     TextView txtName; // so on...   
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.