Monday, August 10, 2009

Custom View in your ListActivity and Custom Adapter in Android

After 2-3 weeks of being absent in Android land, due to over working (going home pass 12am.......), i'm back with another tutorial on how to make your ListActivity have a view that you like or custom view. In order for us to jump right ahead, you must first know that custom view on your ListActivity means custom view per row on the ListView and usually we need to create or its better to create a custom adapter for it.

For this tutorial, i would reference to the Display Contact Names in Android therefore we need to add READ_CONTACTS on our manifest file.

On our custom_list.xml we would have
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
>
  <TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/txtName"
  />

  <TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/txtPhone"
  />

  <TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/txtDisplayName"
  />
</LinearLayout>



Explanation
This would just give us 3 TextView on vertical order, this would be our custom row therefore on your application if you want to customize the row then this is the file that you might want to work upon.



Main.java
public class Main extends ListActivity  {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Cursor contactsCursor = this.managedQuery(People.CONTENT_URI, null, null, null, null);
    this.setListAdapter(new MyContactsAdapter(this,contactsCursor));
  }

  private class MyContactsAdapter extends CursorAdapter{
    private Cursor mCursor;
    private Context mContext;
    private final LayoutInflater mInflater;

    public MyContactsAdapter(Context context, Cursor cursor) {
      super(context, cursor, true);
      mInflater = LayoutInflater.from(context);
      mContext = context;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
      TextView t = (TextView) view.findViewById(R.id.txtName);
      t.setText(cursor.getString(cursor.getColumnIndex(People.NAME)));

      t = (TextView) view.findViewById(R.id.txtDisplayName);
      t.setText(cursor.getString(cursor.getColumnIndex(People.DISPLAY_NAME)));

      t = (TextView) view.findViewById(R.id.txtPhone);
      t.setText(cursor.getString(cursor.getColumnIndex(People.NUMBER)));
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
      final View view = mInflater.inflate(R.layout.custom_list, parent, false);
      return view;
    }
  }
}



Explanation
Query our contacts table
Cursor contactsCursor = this.managedQuery(People.CONTENT_URI, null, null, null, null);

Set the adapter for our ListView
this.setListAdapter(new MyContactsAdapter(this,contactsCursor));

We create a class for our custom adapter named MyContactsAdapter extending it to CursorAdapter (There are a lot of adapter that you could extend upon)
private class MyContactsAdapter extends CursorAdapter

We get the LayoutInflater from the calling context, what this does is that it will inflate your xml to codes via View object. see newView function
mInflater = LayoutInflater.from(context);

On newView function we inflate our layout to the binded view inside CursorAdapter
final View view = mInflater.inflate(R.layout.custom_list, parent, false);

At this point we have our custom_list as the layout of our ListActivity, now what we need is to use it on every row, you would do it with bindView function
public void bindView(View view, Context context, Cursor cursor) { ..... }

The following should be just binding our TextView in xml to our codes and getting values from our cursor and putting that value to the respective TextView
TextView t = (TextView) view.findViewById(R.id.txtName);
t.setText(cursor.getString(cursor.getColumnIndex(People.NAME)));



Notes
Do note that we extend to CursorAdapter here and it might be different on other adapter, like for ArrayAdapter you will use getView function, good luck....


Reference
http://www.google.com/codesearch/p?hl=en&sa=N&cd=1&ct=rc#kZ0MkhnKNzw/trunk/Photostream/src/com/google/android/photostream/LoginActivity.java&q=CursorAdapter%20package:http://apps-for-android\.googlecode\.com

Hope this help.
Post a Comment