SimpleCursorAdapter 原理和实例
SimpleCursorAdapter
1. 原理参见下面代码注释
Cursor cursor = dbHelper.fetchAllCountries(); //cursor中存储需要加载到listView中的条目,可能由一行或者多行组成。每一行可能包含多列数据(多于listview中定义的) //the desired columns to be bound String[] columns = new String[] { CountryDb.KEY_CODE, CountryDb.KEY_NAME, CountryDb.KEY_CONTINENT }; //这个数据结构指定cursor中的那些列将显示到listview每一行中(从多列中挑选需要的) //the XML defined views which the data will be bound to int[] to = new int[] { R.id.code, R.id.name, R.id.continent };//这个数据结构定义listview中各组件的id,由此和上面的的colums形成了map关系,即cursor中某一行的列字段映射到listview中的控件 //create the adapter using the cursor pointing to the desired data //as well as the layout information SimpleCursorAdapter dataAdapter = new SimpleCursorAdapter( this, R.layout.list_row, //listView xml控件名 cursor, //所存数据的cursor columns,//cursor需要的字段定义 to, //映射到XML每个控件的定义 0); ListView listView = (ListView) findViewById(R.id.listView1); // Assign adapter to ListView listView.setAdapter(dataAdapter); //设置adapter,所有cursor中的数据将自动加载
2. 附上一个通过实现SimpleCursorAdapter getView()方法设置行背景颜色的例子
该例子通过检索SQLite数据库构建了基本的listView,但是默认的listView的行条目是不带有斑马线的(相邻行背景颜色不同)。通过继承SimpleCursorAdapter并实现getView()方法可以达到目的。
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>
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>
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; } }
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"); } }
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; } } }