Friday, April 15, 2011

Populating a ListView from external source on Android

Hello again,
There are many tutorials on how to create and manage ListView on Android, the difficulty here is whether you can find a method that will satisfy your needs.
Here is a tutorial on how to best create a ListView and customize it.

First, lets take a look on our Php script that will provide our data.
if (isset($_POST['JSON'])) {
    header('Content-Type: application/json; charset=iso-8859-1');
    $response = array(
        array('id' => '149', 'title' => 'Revolution',
            'artist' => 'Bob Marley', 'duration' => '271'),
        array('id' => '150', 'title' => 'Natural Mystic',
            'artist' => 'Bob Marley', 'duration' => '312'),
        array('id' => '151', 'title' => 'Redemption Song',
            'artist' => 'Bob Marley', 'duration' => '268'),
        array('id' => '152', 'title' => 'No More Trouble',
            'artist' => 'Bob Marley', 'duration' => '285'),
    );
    print_r(json_encode($response));
}
As you can see, we are going to get some tracks from our data source.
Now let's create our android application.
Here is the class that will hold one track, Track.java:
public class Track {
 private int id;
 private String title;
 private String artist;
 private int duration;

 public Track(int id, String title, String artist, int duration) {
  this.id = id;
  this.title = title;
  this.artist = artist;
  this.duration = duration;
 }
 /**
  * ... getters here
  */
}
- The layout for the listView in main.xml

    

- The layout for one row in the list view, this will give us more options to better customize our view, row.xml, the example here is from romain guy here

     
    
        
        
    

Now we are done with the view layout, let's put every thing together.
It is time to write our custom TrackAdapter that extends TrackAdapter
private class TrackAdapter extends ArrayAdapter {
        // a list that will store our tracks
 private List trackList;
 public LineAdapter(Context context, int textViewResourceId,
   List items) {
  super(context, textViewResourceId, items);
  this.trackList = items;
 }
        // this methode returns a single row from the list view
 @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.row, null);
  }
  Track track = trackList.get(position);
  if (track != null) {
   TextView tt = (TextView) v.findViewById(R.id.toptext);
   TextView bt = (TextView) v.findViewById(R.id.bottomtext);
   if (tt != null) {
    tt.setText("Artist: " + track.getArtist());
   }
   if (bt != null) {
    bt.setText("Title: " + track.getTitle());
   }
  }
  return v;
 }
}
This is a private class and should be added under our MainActivity class.

Now, let's fetch the track list from our external source. I have already made a tutorial on how to get data using a Http post method in my previous blog here so we gonna use that except that we are not sending anything to the server. the doRequest methode wont have any parameters.
private List getTracks() {
 String response = Server.doRequest();
 JSONArray json;
 List trackList = new ArrayList();
 int id, duration;
 String title, artist;
 try {
  json = new JSONArray(response);
  for (int i = 0; i < json.length(); i++) {
   id = json.optJSONObject(i).getInt("id");
   duration = json.optJSONObject(i).getInt("duration");
   title = json.optJSONObject(i).getString("title");
   artist = json.optJSONObject(i).getString("artist");
   trackList.add(new Track(id, title, artist, duration));
  }
 } catch (JSONException e) {
  Log.e("Json", e.getMessage(), e.fillInStackTrace());
 }
 return trackList;
}
Finally, all we need to do is make some calls in the onCreate method
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    m_tracks = new ArrayList();
    m_tracks = getTracks();
    this.m_adapter = new TrackAdapter(this, R.layout.row, m_tracks);
    setListAdapter(this.m_adapter);
}
Also we can add ItemClickListner to the list and even more stuffs. For a more detailed tutorial you can check softwarepassion.com Feel free to leave your comments.

1 comment: