List View using SimpleCursorAdapter – Part I

This entry is part 37 of 50 in the series Android Development Primer

Till now we have been populating our List View with a predefined String array using the ArrayAdapter class of Java. Practically, a predefined array is hardly, if ever, used. Most of the times you would want to populate the List View using the data in your Databases. This is precisely what you see in the Contacts list of your phone. Once you add a contact, it is stored in a database and when you open the Contacts list, the list is populated from the data in the database.

Since, here we will be extracting data from our Database, we definitely ill not be using ArrayAdapter. For this we will use SimpleCursorAdapter class. SimpleCursorAdapter just like ArrayAdapter  helps in bridging the data repository to the UI. Remember that as I said earlier there are many ways to populate the ListView. Here I am going to show you one of the most customizable ways around.

So start off an activity and follow along. Complete Source Code is at the bottom.

  • Create the XML layout for the activity and insert a ListView in it.
  • Create another XML named row_item.xml. We will define the layout for a single row in the ListView. Insert a single TextView here and nothing more.
  • Remember that this is one method of doing things. This keeps your ListView customizable to the the single row.
  • Create a new class in your application. Name it DatabaseHelper.java. It will extend SQLiteOpenHelper and will contain all required methods. If you do not know how to do this refer to one of my previous posts here.
  • Also create two static string variables named colName and colAge with values “_id” and “Age” respectively. These will be the names of the columns in our table. (See Source Code for details.)
  • Switch over to the Java file. We will be extending ListActivity.
  • Declare an object of the DatabaseHelper class and SimpleCursorAdapter class globally i.e. inside the class and outside all the methods.
  • Create a new method displayList(). Within this method we need to insert the values in the Database and retrieve all the data from the database.  Write the following lines to do this:
    db.InsertValues();
    Cursor cursor=db.GetAllData();
    
  • Once the data is retrieved, we need to define the source and destination of all the data items. Write the below lines.
    String from [] = new String[]{db.colName};
    int to [] = new int[] {R.id.textView1};
    
  • Now that we have our source and destination for each data item, we need to define the SimpleCursorAdapter.
    dataAdapter = new SimpleCursorAdapter(this, R.layout.row_item, cursor, from, to, 0);
    
  • Now define the ListView and assign the dataAdapter to the ListView.
    ListView lv = getListView();
    lv.setAdapter(dataAdapter);
    
  • Save your work and execute it on an emulator or device.

Array_Adapter3  Array_Adapter2

Understanding the Code

  • The object of the DatabaseHelper class is required because we will need to call the methods and refer to the static variables of that class. Obviously, it cannot be done without objects.
  • Cursor, as I have said in my earlier posts are analogous to a pointer which points to the beginning of the rows returned from a query.
  • The from[ ] and the to[ ] arrays are used to define the source and destination of the data items. It tells Android how and where I want data from my database to be displayed. The actual importance of these will be reflected when we are using more than one row inside a single row of the ListView. I will discuss this in a separate post.
  • The constructor of the SimpleCursorAdapter class used here is
    SimpleCursorAdapter(Context context, int layout, Cursor cursor, String from[], int to[], int flags)
    
  • The above constructor is already comprehensive. We then finally assign the SimpleCursorAdapter to the ListView.

COMPLETE SOURCE CODE

row_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

activity_main.xml

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin" >

    <ListView
        android:id="@+id/android:list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" >
    </ListView>

</RelativeLayout>

DatabaseHelper.java

package com.nero.myfirstapp;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper {

	static String DatabaseName="NeroDB";
	static String colName="_id";
	static String colAge="Age";

	public DatabaseHelper(Context context) {
		super(context, DatabaseName, null, 4);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL("CREATE TABLE IF NOT EXISTS NeroTable(_id VARCHAR, Age INT(3));");
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		db.execSQL("DROP TABLE NeroTable;");
		db.execSQL("CREATE TABLE IF NOT EXISTS NeroTable(_id VARCHAR, Age INT(3));");
	}

	public void InsertValues()
	{
		SQLiteDatabase db = this.getWritableDatabase();
		db.execSQL("INSERT INTO NeroTable VALUES('Vergil', 20);");
        db.execSQL("INSERT INTO NeroTable VALUES('Dante', 20);");
        db.execSQL("INSERT INTO NeroTable VALUES('Nero', 18);");
        db.execSQL("INSERT INTO NeroTable VALUES('Sparda', 40);");
        db.execSQL("INSERT INTO NeroTable VALUES('Arkham', 38);");
        db.execSQL("INSERT INTO NeroTable VALUES('Agni', 35);");
        db.execSQL("INSERT INTO NeroTable VALUES('Rudra', 35);");
        db.execSQL("INSERT INTO NeroTable VALUES('Beowulf', 60);");
        db.execSQL("INSERT INTO NeroTable VALUES('Nevan', 26);");
        db.close();
	}

	public Cursor GetAllData()
	{
		SQLiteDatabase db = this.getReadableDatabase();
		Cursor c = db.rawQuery("SELECT * FROM NeroTable;", null);
		return c;
	}

	public void DeleteTable()
	{
		SQLiteDatabase db = this.getWritableDatabase();
		db.execSQL("DROP TABLE NeroTable;");
	}
}

MainActivity.java

package com.nero.myfirstapp;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class Main extends ListActivity {
	DatabaseHelper db;
	SimpleCursorAdapter dataAdapter;
	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        db = new DatabaseHelper(Main.this);
        displayList();
    }

	public void displayList(){
		db.InsertValues();
		Cursor cursor=db.GetAllData();
		String from [] = new String[]{db.colName};
		int to [] = new int[] {R.id.textView1};
		dataAdapter = new SimpleCursorAdapter(this, R.layout.row_item, cursor, from, to, 0);
		db.close();

		ListView lv = getListView();
		lv.setAdapter(dataAdapter);
       }
}
Series Navigation<< Adding Long Click functionality in List View – Context Menus ClicksList View using Simple Cursor Adapter – Part II >>

One comment on “List View using SimpleCursorAdapter – Part I

  1. Martin Michael Utzon on said:

    HI
    THANK YOU VERY MUCH – THAT WAS WHAT i HAV BEEN LOOKING FORE – A SIMPLE EXAMPLE IN USING simplecursoradapter.
    however – it took me quite a while to be able to compile the code, I got an error in my Logcat, due to the fact that i call db.close() – and then want to continue with other issues – it should be: – but thank you very much for this tutorial
    regards Martin
    public void displayList(){
    db.InsertValues();
    Cursor cursor=db.GetAllData();
    String from [] = new String[]{db.colName};
    int to [] = new int[] {R.id.textView1};
    dataAdapter = new SimpleCursorAdapter(this, R.layout.row_item, cursor, from, to, 0);

    ListView lv = getListView();
    lv.setAdapter(dataAdapter);
    db.close();
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

*

* Copy This Password *

* Type Or Paste Password Here *

42,383 Spam Comments Blocked so far by Spam Free Wordpress

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>