Aakash Gandhi
Aakash Gandhi

Reputation: 253

getting JSON result in custom listview android

i am trying to get json data into a custom listview. when i run the app it shows only blank layout file.

the json source from http://api.androidhive.info/feed/feed.json

here is what i have done

this is main activity class

package com.example.jsonexample;

import java.net.URL;

import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {




TextView name,email;
handlexml obj;
//String url="http://api.androidhive.info/volley/person_object.json";
//String url="http://api.androidhive.info/feed/feed.json";
ListView lv;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //name=(TextView)findViewById(R.id.textView1);
    //email=(TextView)findViewById(R.id.textView2);

    lv=(ListView)findViewById(R.id.listView1);

    lv.setAdapter(new adapterforlist(this));


    //open();



    }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

/*public void open()
{
    obj = new handlexml(url);

    obj.fetchJSON();



    name.setText(obj.getname());
    email.setText(obj.getemail());



}*/


}   

this is custom listview adapter

package com.example.jsonexample;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class adapterforlist extends BaseAdapter{

    Context context;
    TextView tv1,tv2;
    handlexml jobj;

    String url="http://api.androidhive.info/feed/feed.json";
    //String url="http://api.androidhive.info/volley/person_object.json";

    public adapterforlist(Context c) {
        // TODO Auto-generated constructor stub
        this.context=c;

    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public Object getItem(int arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public long getItemId(int arg0) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public View getView(int arg0, View rootview, ViewGroup viewgrp) {
        // TODO Auto-generated method stub

        LayoutInflater ll = (LayoutInflater)context.getSystemService(context.LAYOUT_INFLATER_SERVICE);


        rootview=ll.inflate(R.layout.custom, null, true);
        tv1=(TextView)rootview.findViewById(R.id.textView1);
        tv2=(TextView)rootview.findViewById(R.id.textView2);

        jobj= new handlexml(url);
        jobj.fetchJSON();

        while(jobj.parsingcomplete)
        {
            tv1.setText(jobj.getname());
            tv2.setText(jobj.getemail());
        }




        return rootview;
    }

}

this is json fetching and parsing class

package com.example.jsonexample;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class handlexml {

    String name;
    String email;
    String stringurl;
    boolean parsingcomplete=true;


    public handlexml(String url){

        this.stringurl=url;

        }


    public String getname() {
        return name;
    }


    public String getemail() {

        return email;
    }



    public void readandparseJSON (String in) {

        try {
            JSONObject reader = new JSONObject(in);

            JSONArray feed = reader.getJSONArray("feed");

            JSONObject reader1= feed.getJSONObject(feed.length());

            for (int i=0; i<=reader1.length();i++)
            {
                name=reader1.getString("name");
                email= reader1.getString("url");
            }




            parsingcomplete= false;


        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public void fetchJSON() {
        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    URL url=new URL(stringurl);

                    HttpURLConnection conn= (HttpURLConnection)url.openConnection();

                    conn.setConnectTimeout(15000);
                    conn.setReadTimeout(10000);
                    conn.setRequestMethod("GET");
                    conn.setDoInput(true);

                    conn.connect();


                    InputStream stream = conn.getInputStream();

                    String data =convertStreamToString(stream);

                    readandparseJSON(data);
                    stream.close();


                } catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }




            }
        });

        thread.start();

    }

     static String convertStreamToString(java.io.InputStream is) {
          java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
          return s.hasNext() ? s.next() : "";
       }


}

this is main xml file

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

this is custom xml file for listadapter

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Small Text"
        android:textAppearance="?android:attr/textAppearanceSmall" />

</LinearLayout>

Upvotes: 1

Views: 1957

Answers (1)

Jorge E. Hern&#225;ndez
Jorge E. Hern&#225;ndez

Reputation: 2938

You should not call the jobj.fetchJSON() method in your BaseAdapter class as it is called for each item in the list. This will make your application too slow.

First of all, you need to provide all the data to the BaseAdapter class. A very used practice is by providing this data in its constructor. So, your Base Adapter class constructor and the getView method should look like this:

public class adapterforlist extends BaseAdapter{

    ...
    private List<Feed> feeds;
    public adapterforlist(Context c, List<Feed> feedsList) {
        this.context=c;
        this.feeds = feedsList;
    }

    @Override
    public View getView(int position, View rootview, ViewGroup viewgrp) {

        LayoutInflater ll = (LayoutInflater)context.getSystemService(context.LAYOUT_INFLATER_SERVICE);

        rootview=ll.inflate(R.layout.custom, null, true);
        tv1=(TextView)rootview.findViewById(R.id.textView1);
        tv2=(TextView)rootview.findViewById(R.id.textView2);

        // Create each item of the listView with every item of the data provided via constructor.
        Feed feed = feeds.get(position);
        tv1.setText(feed.getname());
        tv2.setText(feed.getemail());

        return rootview;
    }
    ...
}

Now, for being able to do this you'll need the following:

  1. Create a class to represent the Feed. It can be a simple POJO (Plain Old Java Object).
  2. Fill a list of Feed objects and inject it to the BaseAdapter via contructor.

Your Feed POJO should look like this:

public class Feed {

    private String name;
    private String email;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }

}

And your list of Feed objects can be created in this way;

public List<Feed> readandparseJSON (String in) {

    List<Feed> feeds = new ArrayList<Feed>();

    try {
        JSONObject reader = new JSONObject(in);
        JSONArray feed = reader.getJSONArray("feed");
        JSONObject reader1= feed.getJSONObject(feed.length());

        for (int i=0; i<=reader1.length();i++)
        {
            Feed feed = new Feed();
            feed.setName(reader1.getString("name"));
            feed.setUrl(reader1.getString("url"));
            feeds.add(feed);
        }

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

    return feeds;

}

Please, let me know if you have more questions.

Upvotes: 3

Related Questions