Amazon Gift Cards

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.

7 comments:

john.sasil said...

Hi i am new to android .

can some one guide me designing calendar in Android.

Unknown said...

Thanks, this post helped me to use the proper super() call.

Unknown said...

hi
i have a class with button and on button click i m trying to display the contact name and number.
i made a seperate class and trying to call from main class on button click.
I failed to get the contact name and number .
Pls advice asap.
My id is nitinchopra_7@yahoo.co.in
thanks

Eric Harlow said...

Thanks for the tutorial!

Anonymous said...

Thanks for the tutorial.It helped me a lot

현종서 said...

Thank you so much for sharing this. :)
I hope this tut will help me.

Bear said...

I have a Similar CursorAdapter to you and it works fine. In my row layout xml file I have a TextView where I manually set the text, it does't bind to a cursor. How do I get a reference to the text view so I can change the the text? I thought I would have to first get the view by calling adapter.getView(position, convertView, parent) but I don't know what the param's have to be. All I have is the position.