【Android】13.2 使用自定义的CursorAdapter访问SQLite数据库
分类:C#、Android、VS2015;
创建日期:2016-02-26
一、简介
SQliteDemo1的例子演示了SimpleCursorAdapter的用法,本节我们将使用用途更广的自定义的游标适配器(继承自CursorAdapter的类)来访问SQLite数据库。
1、自定义游标适配器
Android提供的CursorAdapter类提供了高性能的处理视图滚动的方式,特别适用于滚动显示保存在SQLite数据库中的大量数据。
显示SQLite数据库中的数据时,CursorAdapter子类和SimpleCursorAdapter相比具有相同的性能,但是,用继承自CursorAdapter的类显示SQLite中的数据时,它还能让你完全控制每个行视图的布局以及对每行控件属性的操作。
对于给定的SQLite数据库,你仅需要重写下面的两个方法创建CursorAdapter的子类:
- BindView – 要绑定的视图,游标通过它更新显示的数据。
- NewView – 当ListView需要新的视图来显示数据时调用它。CursorAdapter会负责自动管理视图的生命周期。
CursorAdapter不需要获取数据表行数、获取当前项等方法,这是因为这些信息可以通过类中的游标自身来收集。CursorAdapter将视图拆分到BindView和NewView中以后,会自动复用这些视图。
2、创建游标接口(ICursor)
不管你在Activity中如何执行查询,都会返回一个ICursor,这是 Android 提供的 SQLite 数据库游标接口。使用游标接口,你可以:
- 通过使用 getCount() 方法得到结果集中有多少记录;
- 通过 moveToFirst(), moveToNext(), 和 isAfterLast() 方法遍历所有记录;
- 通过 getColumnNames() 得到字段名;
- 通过 getColumnIndex() 转换成字段号;
- 通过 getString(),getInt() 等方法得到给定字段当前记录的值;
- 通过 requery() 方法重新执行查询得到游标;
- 通过 close() 方法释放游标资源;
例如,下面的代码遍历 mytable 表
ICursor result=db.RawQuery("SELECT ID, name, inventory FROM mytable");
result.MoveToFirst();
while (!result.IsAfterLast()) {
int id=result.getInt(0);
string name=result.getString(1);
int inventory=result.getInt(2);
// do something useful with these
result.MoveToNext();
}
result.Close();
一旦应用程序有一个可用的SQLite数据库并为其创建了一个游标接口对象,就可以在Activity中利用SimpleCursorAdapter或者利用继承自CusorAdapter的子类将数据显示在视图中(比如列表视图等)。
二、示例2—使用自定义的游标适配器访问SQLite
该例子演示如何使用自定义的游标适配器访问SQLite。
1、运行截图
2、主要设计步骤
(1)添加ch1302_Main.axml文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ListView android:id="@+id/ch1302ListView1" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
(2)添加ch1302MyDb2.cs文件
using Android.Content; using Android.Database.Sqlite; namespace MyDemos.SrcDemos { public class ch1302MyDb2 : SQLiteOpenHelper { private const string dbName = "ch1302MyDb2.db"; private const int dbVersion = 1; public ch1302MyDb2(Context context) : base(context, dbName, null, dbVersion) { } public override void OnCreate(SQLiteDatabase db) { SQLiteDatabase.DeleteDatabase(new Java.IO.File("", "MyDb2.db")); string sql = "CREATE TABLE [MyTable1] (" + "[_id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE," + "[name] TEXT NOT NULL UNIQUE," + "[age] INTEGER NOT NULL)"; db.ExecSQL(sql); db.ExecSQL("INSERT INTO MyTable1 (name,age) VALUES ('张三一',23)"); db.ExecSQL("INSERT INTO MyTable1 (name,age) VALUES ('李四二',22)"); db.ExecSQL("INSERT INTO MyTable1 (name,age) VALUES ('王五三',19)"); db.ExecSQL("INSERT INTO MyTable1 (name,age) VALUES ('赵六四',21)"); } public override void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //更改数据库版本的操作,如果无版本更改,此处不需要编写任何代码 } } }
(3)添加ch1302CursorAdapter.cs文件
using Android.App; using Android.Content; using Android.Database; using Android.Views; using Android.Widget; namespace MyDemos.SrcDemos { public class ch1302CursorAdapter : CursorAdapter { Activity context; public ch1302CursorAdapter(Activity context, ICursor c, bool autoRequery) : base(context, c, autoRequery) { this.context = context; } public override void BindView(View view, Context context, ICursor cursor) { var textView = view.FindViewById<TextView>(Android.Resource.Id.Text1); // 第0~2列的字段名:_id,name,age textView.Text = $"{cursor.GetString(1)}({cursor.GetInt(2)}岁)"; } public override View NewView(Context context, ICursor cursor, ViewGroup parent) { return this.context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, parent, false); } } }
(4)添加ch1302MainActivity.cs文件
using Android.App; using Android.OS; using Android.Widget; using Android.Database; namespace MyDemos.SrcDemos { [Activity(Label = "【例13-2】SQLite基本用法2")] public class ch1302MainActivity : Activity { private ICursor cursor; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.ch1302_Main); ch1302MyDb2 db = new ch1302MyDb2(this); cursor = db.ReadableDatabase.RawQuery("SELECT * FROM MyTable1", null); var listView = FindViewById<ListView>(Resource.Id.ch1302ListView1); var adapter = new ch1302CursorAdapter(this, cursor, false); listView.Adapter = adapter; listView.ItemClick += (s, e) => { var obj = listView.Adapter.GetItem(e.Position); var cur = (ICursor)obj; // 第0~2列的字段名:_id,name,age var text = $"{cur.GetString(1)}({cur.GetInt(2)}岁)"; Toast.MakeText(this, text, ToastLength.Short).Show(); }; } protected override void OnDestroy() { cursor.Close(); base.OnDestroy(); } } }