08 August 2013

Android, extending listView functinality


Android listViews are pretty useful and pretty simple. You have to get your head around some sort of adapter, but that's no huge issue.

However I've previously never bothered to find out how to get more than one column on a listView. Luckily this is much easier than I first thought. My example uses contentProvidors to setup the cursor, but I think this should work with DB stuff as well. Given a bit of hocus pocus.

I'm not going to go into the contentProvidor stuff here as it's a big subject and developer.android do a pretty good job:
http://developer.android.com/guide/topics/providers/content-provider-basics.html

First setup your activity_main.xml layout file:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
 
 <ListView
  android:id="@+id/listView1"
  android:layout_width="wrap_content"
  android:layout_height="350dp"
  android:layout_alignParentBottom="true"
  android:layout_centerHorizontal="true" >
 </ListView>

</RelativeLayout>


Next add a new xml file to the res/layout folder (mine is named contacts_single.xml):

<?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="horizontal" >

 <TextView
  android:id="@+id/name_entry"
  android:layout_width="100dp"
  android:layout_height="wrap_content" />
 
 <TextView
  android:id="@+id/number_entry"
  android:layout_width="100dp"
  android:layout_height="wrap_content" />

</LinearLayout>


Now move to the MainActivity or wherever your display function will be and you'll need something like this:

private void outputCursor(){
 // Defines a list of columns which we have defined in our cursor, and will be output to listView
 String[] mWordListColumns =
 {
  ContactsContract.Contacts._ID,
  ContactsContract.Contacts.DISPLAY_NAME_PRIMARY
  
 };

 // Defines a list of View IDs. These are IDs of textViews defined in a serperate layout file
 int[] mWordListItems = { R.id.name_entry, R.id.number_entry};

 // Creates a new SimpleCursorAdapter
 SimpleCursorAdapter mCursorAdapter = new SimpleCursorAdapter(
  getApplicationContext(),   // The application's Context object
  R.layout.contacts_single,   // A layout in XML for one row in the ListView
  mCursor,     // The result from the query
  mWordListColumns,    // A string array of column names in the cursor
  mWordListItems,     // An integer array of view IDs in the row layout
  0      // Flags (usually none are needed)
 );

 // Sets the adapter for the ListView
 ListView myListView = (ListView) findViewById(R.id.listView1);
 myListView.setAdapter(mCursorAdapter);
}

That should be all you need. Note the mWordListItems is passed into the adapter and the R.layout.contacts_single reference, telling the adapter to use these custom elements to display its contents. Then we get the ListView from the original activity and set the adapter. Simples!

No comments: