Mike Mike - 2 months ago 8
JSON Question

Generate listview from JSON in android

I am completely new to Android and currently trying to generate listview from JSON array which was pulled from my server, I have read a lot of tutorials with no luck, there is unique way to do that. Could you, please, point some resources good to start.

I have read this page however I am stuck with the following code:

import josecgomez.com.android.dev.webservice.objects.alerts;


giving me "" as no identified resource:

public class AlertsAdapter extends ArrayAdapter<alerts>


Thank you, any help is greatly appreciated!

Answer

JSON & listview ll work like this..

1.displaying a list of items

The Android SDK provides a convenient way to quickly display a list of data using a superclass called android.app.ListActivity. This Activity already provides a ContentView, configured with a ListView, ready to use and populate with data.

The ListView now needs to be given data to display, along with a means to map that data into rows. ListAdaptors provide this mechanism and are set on the underlying ListView of the ListActivity using setListAdaptor.

An Android SDK provided adaptor (ArrayAdaptor) that knows how to handle arrays of arbitrary data into ListViews (The Android SDK also comes with several other ListAdaptors, such as Cursor Adaptors, which can assist when connecting local data storage to a ListView). You also need to provide the adaptor with a layout it can use to render the elements onto each row. In the example below we are using the Android SDK provided layout, simple_list_item_1, which is a single text label–perfect for laying our single strings:

String[] elements = {"Line 1", "Line 2"};
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, elements));

2.customizing the look of each list item

In order to achieve this you will have to move beyond the inbuilt layout and ArrayAdaptor and implement your own instead.

Start by creating a class ABC that can be used to hold both the author and the content as Strings. Then create and populate a object with some test data to be displayed in the custom list item:

public class ABC {
    String userId;
    String pwd;
}

Create a layout XML file in /res/layout/list_item.xml to define two TextViews to display the content and author on separate rows. In order to display them one above the other, use a LinearLayout, configured to render each element within it vertically (android:orientation="vertical").

Once the XML file has been created, the Android Eclipse plugin will automatically add it as a reference into the generated R file. This R file is kept under the /gen folder of your project and acts as a bridge between your XML elements and your Java code. It allows your Java code to reference XML elements and files created under the /res folders. The file you have just created can now be referenced as R.layout.list_item in the Java code, as you will do next in the custom list adaptor.

Create a private class (inside the Activity) called ListAdaptor which subclasses ArrayAdaptor. This class should be used to store an ArrayList being displayed, as well as providing a way to map the objects to the TextViews you created in the layout above.

This mapping overrides the ListAdaptor, and should return a View object populated with the contents of the data at the requested position.

The complete implementation of the custom abcListAdaptor is below:

private class abcListAdaptor extends ArrayAdapter<abc> {  
    private ArrayList<abc> abc;  
    public abcListAdaptor(Context context, int textViewResourceId, ArrayList<abc> items) {  
        super(context, textViewResourceId, items);  
        this.abc = items;  
    }  

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

        if (v == null) {  
            LayoutInflater vi = (LayoutInflater) getSystemService                          
(Context.LAYOUT_INFLATER_SERVICE);  
            v = vi.inflate(R.layout.list_item, null);  
        }  

        abc o = abc.get(position);  
        TextView tt = (TextView) v.findViewById(R.id.uid);  
        TextView bt = (TextView) v.findViewById(R.id.pwd);  
        tt.setText(o.userid);  
        bt.setText(o.pwd);  
        return v;  
    }  
}  

Now the onCreate method can be adjusted to use the custom list adaptor with the created test data as shown below:

public void onCreate(Bundle savedInstanceState) {  
super.onCreate(savedInstanceState);  
abc a = new abc();  
a.userid = "tech";  
a.pwd = "android";  
ArrayList<abc> items = new ArrayList<abc>();  
items.add(a);  
abcListAdaptor adaptor = new abcListAdaptor(this,R.layout.list_item, items);  
setListAdapter(adaptor);  
}  

3.accessing remote services and parsing data

The Android SDK contains packages aimed at simplifying access to HTTP-based APIs. The Apache HTTP classes have been included and can be found under the org.apache.http package. You’ll be using these classes, along with the org.json classes to parse the data coming back from a server.

we can create a private method in the Activity that makes a request, parses the result, and returns an ArrayList of objects. The code listed below makes the request and looks for the resulting JSON array, which is iterated to extract each text and from_user elements.

ArrayList<abc> getDetail= new ArrayList<abc>();  
    try {  
        HttpClient hc = new DefaultHttpClient();  
        HttpGet get = new  
        HttpGet("<a href="http://your URL"></a>");  
        HttpResponse rp = hc.execute(get);  

        if(rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
            String result = EntityUtils.toString(rp.getEntity());  
            JSONObject root = new JSONObject(result);  
            JSONArray sessions = root.getJSONArray("results");  

            for (int i = 0; i < sessions.length(); i++) {  
                JSONObject session = sessions.getJSONObject(i);  
                abc a = new abc();  
                a.uid = session.getString("user");  
                a.pwd = session.getString("password");  
                getDetail.add(a);  
            }  
        }  
    } 

    catch (Exception e) {  
        Log.e("Activity", "Error loading JSON", e);  
    }  

Now replace the dummy data you previously used with a call to the load method when constructing the custom list adaptor in the onCreate method.

abcListAdaptor adaptor = new abcListAdaptor(this,R.layout.list_item, load());  

4.creating responsive user interfaces

The code in its current state has the potential to cause an Application Not Responding (ANR) dialog to appear, prompting the user to quit your app. This can occur due to the long-running work of making a remote request for data being performed within methods such as onCreate.

Long-running tasks should never be performed on the main application thread (which drives the user interface event loop). They should instead be spawned off into child threads to perform the work.

While Java’s Thread class can be used for this task, there is a complication in that once the long-running task is complete, it generally wants to change the user interface to report the results (that is, display a list of loaded from a request).

User interface elements can only have their state altered from the main thread, as the Android UI toolkit is not thread-safe, therefore the background thread needs to message back to the main thread in order to manipulate the UI.

Thankfully, the Android SDK provides a convenient class AsyncTask, which provides an easy mechanism for asynchronous tasks to interact safely with the UI thread. This is achieved by subclassing AsyncTask and overriding the doInBackground method to perform the long-running task, then overriding onPostExecute to perform any manipulations on the UI.

When the AsyncTask is created (it has to be created on the UI thread) and executed, the doInBackground method is invoked on a background thread. On completion, the onPostExecute method is invoked back on the main UI thread.

To use this in your app, you will need to implement a private class within the Activity (like the custom adaptor class) called MyTask, which subclasses AsyncTask. You can override the doInBackground method with the contents of your previous load method.

Instead of the ArrayList being returned, you maintain an instance variable in the Activity so that the data can be shared across the private classes. Then in the onPostExecute you can set the List Adaptor with the data, as was done previously in onCreate. The onCreate method now simply creates the MyTask object and calls the execute method.

Best Sites for listView are this & this.

--

Regards

TechEnd