Last Updated: September 29, 2021
·
65.93K
· sisardor

Android CursorAdapter with custom layout and how to use it

Android provides adapter classes specifically to display data from an SQLite database query. There is SimpleCursorAdapter class, which is more simpler and you cannot use your own custom xml layout and you don't have the control of the layout. In order to use custom xml layout, Android provides CursorAdapter.

A CursorAdapter makes it easy to use when the resource of a listview is coming from database and you can have more control over the binding of data values to layout controls. In the newView() method, you simply inflate the view and return it. In the bindView() method, you set the elements of your view.

1) CursorAdapter

Create new class

First, create new class which extends CursorAdapter and give it a name. This new CursorAdapter class must implement the inherited abstract methods as following

public class MyCursorAdapter extends CursorAdapter {

    // Default constructor
    public MyCursorAdapter(Context context, Cursor cursor, int flags) {
        ...
    }

    public void bindView(View view, Context context, Cursor cursor) {
        ...
    }

    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        ...
        return null;
    }
}

Next define the methods of MyCursorAdapter

In BaseAdapter, view is created in getView method; in CursorAdapter, however, view is created in newView() method and elements are populated in bindView(). In the newView() method, you simply inflate the view your custom xml and return it. In the bindView() method, you set the elements of your view.
Here is code:

public class MyCursorAdapter extends CursorAdapter {
    private LayoutInflater cursorInflater;

    // Default constructor
    public MyCursorAdapter(Context context, Cursor cursor, int flags) {
       super(context, c, flags);
       cursorInflater = (LayoutInflater) context.getSystemService(
                     Context.LAYOUT_INFLATER_SERVICE);
       ...
    }

    public void bindView(View view, Context context, Cursor cursor) {
       TextView textViewTitle = (TextView) view.findViewById(R.id.articleTitle);
       String title = cursor.getString( cursor.getColumnIndex( MyTable.COLUMN_TITLE ) )
       textViewTitle.setText(title);
       ...
    }

    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        // R.layout.list_row is your xml layout for each row
        return cursorInflater.inflate(R.layout.list_row, parent, false);
    }
}

2) MainActivity class

Main Activity setup

Since loading data from database is heavy-duty job, we will load the data in the Thread. If you do not explicitly start CursorAdapter in its own thread then it will run on the main (UI) thread which may be noticeable as jittery or slow to respond interface by your users. Here we'll use android Handler

public class MainActivity extends Activity {
    MyCursorAdapter customAdapter;
    private Cursor mCursor;
    private ListView listView;

    // Default constructor
    public onCreate(Bundle savedInstanceState) {
        ...
        listView = (ListView) findViewById(R.id.main_layout);

        // Your database schema
        String[] mProjection = { 
                MyTable.COLUMN_ID, 
                MyTable.COLUMN_TITLE,
        };

        // Here we query database
        mCursor =  getContentResolver().query(
                MyAdContentProvider.CONTENT_URI,
                mProjection, 
                null,   
                null,                                       
                null);


        listView.setOnItemClickListener(new OnItemClickListener() {
                ...
        }):
    }

    new Handler().post(new Runnable() {

        @Override
        public void run() {
            customAdapter = new MyCursorAdapter(
                MainActivity.this, 
                mCursor,
                0);

            listView.setAdapter(customAdapter);
        }

    });

}

4 Responses
Add your response

Currently i am trying to develop a quiz app for android.For that i populated questions and options from the database using listview with cursor adapter but it retrieves ony one ques at a time or it retrieves all the ques at a time.so can u please help me in retrieving ques one by one from the db?is it possible?

over 1 year ago ·

Hi there. I do like your tutorial on cursor adapter. Thanks for that!!

*On a side note, I'd like to notify you that several times I clicked on this link from google search results, I did get a warning on safety on this site. There was a red diagonal strikethrough on the [http] part followed by a warning. However, after like 3 trials I eventually arrived on this page and there were no more warnings on security. I'm using google chrome. Please take a look at it! Thanks!

over 1 year ago ·

Hello, I read your this post and it helped me to create a custom adapter extending a cursor adapter for my app.
But i have some questions and errors after creating the adapter and using it for the app.
How does the bindView method collect the cursor data coming from the main activity if we are not calling this method like CustomAdapter ca = new CustomAdapter(context, cursor, flags);
listview.setAdapter(ca);

before listview.set......y not call ca.bindView(3 arguments for it); ??

After running the app i have one error of nullpointerexception when in bindView method i am trying to set the text for a textview using the cursor object....Need your help for this.....Thanks....

over 1 year ago ·

Good article, but I have one question. How to add a button to the list and set a listener. I tried, unfortunately, I couldn't do it. Add button it is not problem, problem is set a listener

over 1 year ago ·