Android: List view from Database with Cursor Adapter


I updated the code and solved the issues regarding running on lower API android.
I have tested on android version 2.1 (api level 7)

How to use:

1st screen is an empty list view.
Click on Enter Data button on first screen
2nd screen is a form view. add data to the text boxes and click add button
this data will be saved to database and take you to the first screen

Key Points

Cursor adapter is specialized adapter for a list view, when the data comes from database.


it has a list view, currently empty.
this list view will be populated with data coming from database

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android=""
              android:orientation="vertical" >

    <ListView android:id="@+id/list_data"

    <Button android:layout_width="match_parent"
            android:text="Enter Data"



two text boxes for entering data and the data will be saved in database

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""
              android:layout_height="fill_parent" >

    <EditText android:id="@+id/et_person_name"
              android:hint="Enter Name"

    <EditText android:id="@+id/et_person_pin"
              android:hint="Enter PIN"

    <Button android:layout_width="match_parent"



this xml is responsible for how each item in list view will be looked

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android=""

    <TextView android:id="@+id/tv_person_name"
              android:text="Sample Data"
              android:paddingBottom="5dp" />

    <TextView android:id="@+id/tv_person_pin"
              android:text="Sample Data 2"
              android:paddingBottom="5dp" />


package com.example;

import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.TextView;

public class CustomCursorAdapter extends CursorAdapter {

    public CustomCursorAdapter(Context context, Cursor c) {
        super(context, c);

    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        // when the view will be created for first time,
        // we need to tell the adapters, how each item will look
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View retView = inflater.inflate(R.layout.single_row_item, parent, false);

        return retView;

    public void bindView(View view, Context context, Cursor cursor) {
        // here we are setting our data
        // that means, take the data from the cursor and put it in views

        TextView textViewPersonName = (TextView) view.findViewById(;

        TextView textViewPersonPIN = (TextView) view.findViewById(;

package com.example;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

public class EnterDataActivity extends Activity {

    EditText editTextPersonName;
    EditText editTextPersionPIN;

     * Called when the activity is first created.
    public void onCreate(Bundle savedInstanceState) {


        editTextPersonName = (EditText) findViewById(;
        editTextPersionPIN = (EditText) findViewById(;

    public void onClickAdd (View btnAdd) {

        String personName = editTextPersonName.getText().toString();
        String personPIN = editTextPersionPIN.getText().toString();

        if ( personName.length() != 0 && personPIN.length() != 0 ) {

            Intent newIntent = getIntent();
            newIntent.putExtra("tag_person_name", personName);
            newIntent.putExtra("tag_person_pin", personPIN);

            this.setResult(RESULT_OK, newIntent);


package com.example;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

public class MyActivity extends Activity {
    private CustomCursorAdapter customAdapter;
    private PersonDatabaseHelper databaseHelper;
    private static final int ENTER_DATA_REQUEST_CODE = 1;
    private ListView listView;
    private static final String TAG = MyActivity.class.getSimpleName();
     * Called when the activity is first created.
    public void onCreate(Bundle savedInstanceState) {
        databaseHelper = new PersonDatabaseHelper(this);
        listView = (ListView) findViewById(;
        listView.setOnItemClickListener(new OnItemClickListener() {

			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				Log.d(TAG, "clicked on item: " + position);
        // Database query can be a time consuming task ..
        // so its safe to call database query in another thread
        // Handler, will handle this stuff for you <img src="" alt=":)" class="wp-smiley">
        new Handler().post(new Runnable() {
            public void run() {
                customAdapter = new CustomCursorAdapter(MyActivity.this, databaseHelper.getAllData());
    public void onClickEnterData(View btnAdd) {
        startActivityForResult(new Intent(this, EnterDataActivity.class), ENTER_DATA_REQUEST_CODE);
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == ENTER_DATA_REQUEST_CODE && resultCode == RESULT_OK) {

            databaseHelper.insertData(data.getExtras().getString("tag_person_name"), data.getExtras().getString("tag_person_pin"));


package com.example;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class PersonDatabaseHelper {

    private static final String TAG = PersonDatabaseHelper.class.getSimpleName();

    // database configuration
    // if you want the onUpgrade to run then change the database_version
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "mydatabase.db";

    // table configuration
    private static final String TABLE_NAME = "person_table";         // Table name
    private static final String PERSON_TABLE_COLUMN_ID = "_id";     // a column named "_id" is required for cursor
    private static final String PERSON_TABLE_COLUMN_NAME = "person_name";
    private static final String PERSON_TABLE_COLUMN_PIN = "person_pin";

    private DatabaseOpenHelper openHelper;
    private SQLiteDatabase database;

    // this is a wrapper class. that means, from outside world, anyone will communicate with PersonDatabaseHelper,
	// but under the hood actually DatabaseOpenHelper class will perform database CRUD operations 
    public PersonDatabaseHelper(Context aContext) {
        openHelper = new DatabaseOpenHelper(aContext);
        database = openHelper.getWritableDatabase();

    public void insertData (String aPersonName, String aPersonPin) {

        // we are using ContentValues to avoid sql format errors

        ContentValues contentValues = new ContentValues();

        contentValues.put(PERSON_TABLE_COLUMN_NAME, aPersonName);
        contentValues.put(PERSON_TABLE_COLUMN_PIN, aPersonPin);

        database.insert(TABLE_NAME, null, contentValues);

    public Cursor getAllData () {

        String buildSQL = "SELECT * FROM " + TABLE_NAME;

        Log.d(TAG, "getAllData SQL: " + buildSQL);

        return database.rawQuery(buildSQL, null);

	// this DatabaseOpenHelper class will actually be used to perform database related operation 
    private class DatabaseOpenHelper extends SQLiteOpenHelper {

        public DatabaseOpenHelper(Context aContext) {
            super(aContext, DATABASE_NAME, null, DATABASE_VERSION);

        public void onCreate(SQLiteDatabase sqLiteDatabase) {
            // Create your tables here


            Log.d(TAG, "onCreate SQL: " + buildSQL);


        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
            // Database schema upgrade code goes here

            String buildSQL = "DROP TABLE IF EXISTS " + TABLE_NAME;

            Log.d(TAG, "onUpgrade SQL: " + buildSQL);

            sqLiteDatabase.execSQL(buildSQL);       // drop previous table

            onCreate(sqLiteDatabase);               // create the table from the beginning


there is nothing special in this AndroidManifest file. still i am including this one, in case you need to see something

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=""
    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="17"/>
    <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
        <activity android:name="MyActivity"
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>

        <activity android:name=".EnterDataActivity"/>

49 thoughts on “Android: List view from Database with Cursor Adapter


    11-23 07:07:24.811: E/AndroidRuntime(1515): FATAL EXCEPTION: Thread-184
    11-23 07:07:24.811: E/AndroidRuntime(1515): java.lang.RuntimeException: Can’t create handler inside thread that has not called Looper.prepare()
    11-23 07:07:24.811: E/AndroidRuntime(1515): at android.os.Handler.(
    11-23 07:07:24.811: E/AndroidRuntime(1515): at android.widget.CursorAdapter$ChangeObserver.(
    11-23 07:07:24.811: E/AndroidRuntime(1515): at android.widget.CursorAdapter.init(
    11-23 07:07:24.811: E/AndroidRuntime(1515): at android.widget.CursorAdapter.(
    11-23 07:07:24.811: E/AndroidRuntime(1515): at com.example.listviewwithdatabase.CustomAdapter.(
    11-23 07:07:24.811: E/AndroidRuntime(1515): at com.example.listviewwithdatabase.MainActivity$

    please can i knw the reason

  2. public CustomAdapter(Context context, Cursor c, int flags) {
    super(context, c, flags); //////ERROR

    It has error in second line

  3. @Kushi and Dhivya
    the solution is in the error message
    just add this line, Looper.prepare();
    at, line number: 35

    previously it worked just fine .. newer android versions need this procedure

  4. i’ve add Looper.prepare(); but super(context, c, flags); this line has error like that,
    The constructor CursorAdapter(Context, Cursor, int) is undefined

  5. @aybala
    I have updated the code, now it would works for lower android version as well .. thank you all for keep patience and correct my mistakes 🙂

  6. Everything ok and also i got clear output. But i can’t clearly understand the source code have some difficult topics. If you have time please help me “Put the hint in source code in each and every line and send it to me through mail”

  7. It’s useful example
    When it runs on emulator
    I clicked Enter Data button , “The project has stopped” mesaage appered on the screen .
    I try to debug it.
    Thread [ main] (Suspended (exception IllegalStateException))
    Help me please

  8. List Items are not clickable. ofcourse i can add to them a longclicklistener but they dont show like being clicked or long clicked.
    what can be the problem?

    this is my cursor adapter.
    public class CustomListAdapter extends CursorAdapter {

    public CustomListAdapter(Context context, Cursor c, int flags) {
    super(context, c, flags);
    inflater = LayoutInflater.from(context);

    LayoutInflater inflater;
    Context context;
    private TextView eventName;
    private CheckBox eventSelected;

    public void bindView(View arg0, Context arg1, final Cursor arg2) {
    final int position = arg2.getPosition();
    eventSelected = (CheckBox) arg0
    eventName = (TextView) arg0.findViewById(;
    boolean state = arg2.getString(
    .equalsIgnoreCase(“1”) ? true : false;
    // get view recycles so we need to set it null here

    .setOnCheckedChangeListener(new OnCheckedChangeListener() {
    public void onCheckedChanged(CompoundButton buttonView,
    boolean isChecked) {
    int ruleId = arg2.getInt(0);
    updateRuleState(ruleId, isChecked);


    i am using this layout for list item . that is bing inflated.

  9. your comment is good bt its nt useful for me. when i click on image of delete which is on listview that item of listview will be deleted i want that type of code thnx 4 your reply…

  10. @megha,
    sorry for the delayed reply ..
    I am planning to update the example with insertion, update and delete list item and also following an object oriented approach
    I will post the example soon as i get some time from my work. Thanks for your patience.

  11. @Adolfo Ariza
    simply add the code after line #39 in

    listView.setOnItemClickListener(new ListView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  12. @megha,
    I have included the portion in .. should work without a problem .. when you click on list item, a debug log will be printed with tag “MyActivity”

  13. This allows your lungs to heal itself and expand properly which allows you to breathe effectively.
    When purchasing raw garlic, choose plump, firm, white bulbs with the papery skin still intact on the bulb.
    Form a paste made from crushed garlic to help cure a nosebleed.

  14. Wow, this is what i really needed, Thanx! Now can i start with my own project. I Hope the update and delete code will be as understandable as the other code.

  15. Hi, Where and how can you fill your database only the first tiime you start your app?

    I tried in in DatabaseOpenHelperClass in Oncreate but it isn’t working

  16. @maarten,
    there are two cases
    1. do you want to fill the database every time you start app? or,
    2. fill the database only once in the lifetime of app?

    1. you can put the data populate code in Application Initialization state. This may help, Application Class

    2. You may use Shared preference.
    Shared Preference

  17. Great help. Let me know if you extend this to include buttons on the listview rows and how to respond to them. Thanks again.

  18. Hi, this is great tutorial. It helped me a lot but How can I remove a listitem in this listview? I want to create a delete button.

  19. In your example Activity you comment:
    // Database query can be a time consuming task ..
    // so its safe to call database query in another thread
    // Handler, will handle this stuff for you
    But you do not create the handler on a separate thread. This way the query still runs on the main thread and can cause an ANR. And when running the same code on a separate thread, you cannot touch the views on the main thread.
    You should use an AsyncTask in this case:

    new AsyncTask() {

    protected Cursor doInBackground(Void… params) {
    return databaseHelper.getAllData();

    protected void onPostExecute(Cursor result) {
    customAdapter = new CustomCursorAdapter(MyActivity.this, result);

  20. in above “List view from Database with Cursor Adapter” blog only insert code is given. please give me update and delete code in same project.

  21. Very Nice……………..
    lot of thanx……

    But when I add another column and edit in all files then app is crashed…. what can I do…. ?
    I need to add more than 7 columns…
    Help Me……

  22. Enter values in edittext after click on save button values not displaying in listview what’s the problem i cant understand.

  23. I want to do the same app but by using mysql.
    I have already make the registration and login part, and now i want to get the user information from databse and add this information into a listview using mysql.
    Can you Help me please?

  24. 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 can u please help me in retrieving ques one by one from the db?is it possible?

  25. I’m making a school marks app so I put the name of the exam and in the pin I put the mark of the exam. How can I make the average of all the marks of the exams that I enter ?? And another thing, how can I delete an item of the list view and also on the database? thx

  26. Hi i need one think for when i am click to list view, i want to get all details from database to display in the another activity.

  27. Thank you so much.. searching for all the day for an clear and simple method for implement SQL DB on my project and your post is perfect! THANKS! =)

  28. About the handler for database query, handler is still in the UI thread so it still blocks the UI thread. So you need to create AsyncTask. Another problem is that cursor is lazy loaded, it will be loaded only when it is used, therefore,it should be loaded before onPostExecute, which runs on the UI thread.

  29. Magnificent goods from you, man. I’ve understand your stuff previous to and you are just extremely wonderful.
    I really like what you’ve acquired here, really like what you are stating and the way in which you say
    it. You make it entertaining and you still care for to
    keep it sensible. I can’t wait to read much more from you.

    This is really a great website.

  30. First of alll I would like to say terrific blog!
    I had a quick question that I’d like to ask if you
    do not mind. I wwas interested too find out how
    you center yourself and clear your mind prior to writing.

    I’ve hhad difficulty clearing my mind in getting my thokughts out there.
    Iddo takie pleasure in writing but itt just seems like the first 10 to
    15 mjnutes are usually wasted simply just trying to figure out
    how to begin. Any ideas or tips? Thanks!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.