Android SimpleCursorAdapter alternate Row Color example

To change the background color of a row in ListView you have to use a custom Adapter. In this example we display a basic ListView from SQLite database using the SimpleCursorAdapter which by default doesn't have the zebra stripes on the rows. So to achieve our alternate colors for each row we extend the SimpleCursorAdapter to create a custom class and override the getView method.

Android SimpleCursorAdapter alternate Row Color example

Source for Main Activity Layout - 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"
    tools:context=".MainActivity"
    android:padding="10dp" >

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

Source for ListView Row Layout - list_row.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="5dip" >

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Medium Text"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/name"
        android:layout_toRightOf="@+id/name"
        android:text=" - "
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:id="@+id/code"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/textView1"
        android:text="Medium Text"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="false"
        android:layout_alignParentLeft="true"
        android:layout_below="@id/name"
        android:text="Continent is "
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:id="@+id/continent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/textView2"
        android:layout_alignBottom="@+id/textView2"
        android:layout_toRightOf="@+id/textView2"
        android:text="Medium Text"
        android:textAppearance="?android:attr/textAppearanceMedium" />
    
</RelativeLayout>

Source for Country POJO - Country.java

package com.as400samplecode;

public class Country {
 
 String code = null;
 String name = null;
 String continent = null;
 
 public String getCode() {
  return code;
 }
 public void setCode(String code) {
  this.code = code;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getContinent() {
  return continent;
 }
 public void setContinent(String continent) {
  this.continent = continent;
 }
 
}

Source for Country SQLite Db Adapter - CountryDb.java

package com.as400samplecode;

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

public class CountryDb {

 public static final String KEY_ROWID = "_id";
 public static final String KEY_CODE = "code";
 public static final String KEY_NAME = "name";
 public static final String KEY_CONTINENT = "continent";
 
 private static final String TAG = "CountriesDbAdapter";
 private DatabaseHelper mDbHelper;
 private SQLiteDatabase mDb;

 private static final String DATABASE_NAME = "World";
 private static final String SQLITE_TABLE = "Country";
 private static final int DATABASE_VERSION = 1;

 private final Context mCtx;

 private static final String DATABASE_CREATE =
  "CREATE TABLE if not exists " + SQLITE_TABLE + " (" +
  KEY_ROWID + " integer PRIMARY KEY autoincrement," +
  KEY_CODE + "," +
  KEY_NAME + "," +
  KEY_CONTINENT + "," +
  " UNIQUE (" + KEY_CODE +"));";

 private static class DatabaseHelper extends SQLiteOpenHelper {

  DatabaseHelper(Context context) {
   super(context, DATABASE_NAME, null, DATABASE_VERSION);
  }


  @Override
  public void onCreate(SQLiteDatabase db) {
   Log.w(TAG, DATABASE_CREATE);
   db.execSQL(DATABASE_CREATE);
  }

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
   Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
     + newVersion + ", which will destroy all old data");
   db.execSQL("DROP TABLE IF EXISTS " + SQLITE_TABLE);
   onCreate(db);
  }
 }

 public CountryDb(Context ctx) {
  this.mCtx = ctx;
 }

 public CountryDb open() throws SQLException {
  mDbHelper = new DatabaseHelper(mCtx);
  mDb = mDbHelper.getWritableDatabase();
  return this;
 }

 public void close() {
  if (mDbHelper != null) {
   mDbHelper.close();
  }
 }

 public long createCountry(String code, String name, String continent) {

  ContentValues initialValues = new ContentValues();
  initialValues.put(KEY_CODE, code);
  initialValues.put(KEY_NAME, name);
  initialValues.put(KEY_CONTINENT, continent);
  
  return mDb.insert(SQLITE_TABLE, null, initialValues);
 }

 public boolean deleteAllCountries() {

  int doneDelete = 0;
  doneDelete = mDb.delete(SQLITE_TABLE, null , null);
  Log.w(TAG, Integer.toString(doneDelete));
  return doneDelete > 0;

 }

 public Cursor fetchAllCountries() {

  Cursor mCursor = mDb.query(SQLITE_TABLE, new String[] {KEY_ROWID,
    KEY_CODE, KEY_NAME, KEY_CONTINENT}, 
    null, null, null, null, null);

  if (mCursor != null) {
   mCursor.moveToFirst();
  }
  return mCursor;
 }

 public void insertSomeCountries() {

  createCountry("AFG","Afghanistan","Asia");
  createCountry("CHN","China","Asia");
  createCountry("ALB","Albania","Europe");
  createCountry("DZA","Algeria","Africa");
  createCountry("ASM","American Samoa","Oceania");
  createCountry("AND","Andorra","Europe");
  createCountry("AGO","Angola","Africa");
  createCountry("AIA","Anguilla","North America");
  createCountry("USA","United States","North America");
  createCountry("CAN","Canada","North America");

 }

}

Source for Android Main Activity - MainActivity.java

package com.as400samplecode;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Color;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class MainActivity extends Activity {

 private CountryDb dbHelper;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  dbHelper = new CountryDb(this);
  dbHelper.open();

  //Clean all data
  dbHelper.deleteAllCountries();
  //Add some data
  dbHelper.insertSomeCountries();

  //Generate ListView from SQLite Database
  displayListView();

 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.activity_main, menu);
  return true;
 }

 private void displayListView() {

  Cursor cursor = dbHelper.fetchAllCountries();

  //the desired columns to be bound
  String[] columns = new String[] {
    CountryDb.KEY_CODE,
    CountryDb.KEY_NAME,
    CountryDb.KEY_CONTINENT
  };

  //the XML defined views which the data will be bound to
  int[] to = new int[] { 
    R.id.code,
    R.id.name,
    R.id.continent
  };

  //create the adapter using the cursor pointing to the desired data 
  //as well as the layout information
  MyCursorAdapter dataAdapter = new MyCursorAdapter(
    this, R.layout.list_row, 
    cursor, 
    columns, 
    to,
    0);

  ListView listView = (ListView) findViewById(R.id.listView1);
  // Assign adapter to ListView
  listView.setAdapter(dataAdapter);


 }

 //extend the SimpleCursorAdapter to create a custom class where we 
 //can override the getView to change the row colors
 private class MyCursorAdapter extends SimpleCursorAdapter{

  public MyCursorAdapter(Context context, int layout, Cursor c,
    String[] from, int[] to, int flags) {
   super(context, layout, c, from, to, flags);
  }  

  @Override  
  public View getView(int position, View convertView, ViewGroup parent) {  

   //get reference to the row
   View view = super.getView(position, convertView, parent); 
   //check for odd or even to set alternate colors to the row background
   if(position % 2 == 0){  
    view.setBackgroundColor(Color.rgb(238, 233, 233));
   }
   else {
    view.setBackgroundColor(Color.rgb(255, 255, 255));
   }
   return view;  
  }  


 }  


}

No comments:

Post a Comment

NO JUNK, Please try to keep this clean and related to the topic at hand.
Comments are for users to ask questions, collaborate or improve on existing.