【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 = ; 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();
}
}
}
【Android】13.2 使用自定义的CursorAdapter访问SQLite数据库的更多相关文章
- 【Android】13.0 第13章 创建和访问SQLite数据库—本章示例主界面
		
分类:C#.Android.VS2015: 创建日期:2016-02-26 一.简介 Android 内置了三种数据存取方式:SQLite数据库.文件.SharedPreferences. 这一章我们 ...
 - 【Android】13.1 用Android自带的API访问SQLite数据库
		
分类:C#.Android.VS2015: 创建日期:2016-02-26 一.简介 这一节我们先来看看如何直接用Android自带的API创建和访问SQLite数据库. 1.创建SQLite数据库 ...
 - 【Android】13.4 使用SQLite.NET.Async-PCL访问SQLite数据库
		
分类:C#.Android.VS2015: 创建日期:2016-02-27 一.简介 这一节演示如何利用以异步方式(async.await)访问SQLite数据库. 二.示例4运行截图 下面左图为初始 ...
 - Qt5 开发 iOS 应用之访问 SQLite 数据库
		
开发环境: macOS 10.12.1 Xcode 8.1 Qt 5.8 iPhone 6S+iOS 10.1.1 源代码: 我在 Qt 程序里指定了数据库的名称来创建数据库,在 Win10.An ...
 - 并发访问sqlite数据库出现databse is locked的错误的一个解决办法
		
作者:朱金灿 来源:http://blog.csdn.net/clever101 在并发访问sqlite数据库会出现这样一个错误:databseis locked,这是sqlite数据库对并发支持不太 ...
 - 【C#】使用EF访问Sqlite数据库
		
原文:[C#]使用EF访问Sqlite数据库 1. 先上Nuget下载对应的包 如图,搜索System.Data.SQLite下载安装即可,下载完之后带上依赖一共有这么几个: EntityFramew ...
 - 以EntifyFramework DBFirst方式访问SQLite数据库
		
前面一直在找EF Code First方式来访问SQLite数据库,后面得出的结论是SQLite不支持 Code First, 虽然有非官方的库SQLite.CodeFirst可以使用,但一直没搞成功 ...
 - 【Android】13.3 使用SQLite.NET-PCL访问SQLite数据库
		
分类:C#.Android.VS2015: 创建日期:2016-02-26 一.简介 本章开头已经说过了,SQLite.NET-PCL用起来很爽,这一节咱们看看怎样使用吧. 二.示例3运行截图 下面左 ...
 - Android开发8:数据存储(二)——SQLite数据库和ContentProvider的使用
		
前言 啦啦啦各位小伙伴们许久不见了~学期末和过年期间自己忙着做其他事没能及时更新Android开发系列课程的博客,实在是罪过罪过~ 好啦~废话不多说,进入我们今天的主题.今天我们将和大家学习其他的数据 ...
 
随机推荐
- 【翻译自mos文章】job 不能自己主动运行的解决方法
			
job 不能自己主动运行的解决方法 參考原文: Jobs do not execute automatically (Doc ID 309945.1) 适用于: Oracle Server - Ent ...
 - UIControl的子类UISwitch, UISegmentedCntrol, UIPageControl详解
			
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typica ...
 - 解决用户自生成meta导入kylin后报错问题Can not deserialize instance of java.lang.String[] out of VALUE_STRING token
			
报错栈: -- ::, ERROR [http-bio--exec-] cube.CubeManager: : Error during load cube instance, skipping : ...
 - 完全理解Gson(2):Gson序列化
			
通过调用 Gson API 可以把 Java 对象转换为 JSON 格式的字符串(项目主页).在这篇文章中,我们将会讲到如何通过 Gson 默认实现和自定义实现方式,将 Java 对象转换为 JSO ...
 - iOS开源项目:DYNavigationController
			
DYNavigationController是一个实现了左右滑动导航的项目. https://github.com/dyang/DYNavigationController 首先用之前的跟视图初始化D ...
 - 3 cocos2dx 3.0 源码分析-mainLoop详细
			
简述: 我靠上面图是不是太大了, 有点看不清了. 总结一下过程: 之前说过的appController 之后经过了若干初始化, 最后调用了displayLinker 的定时调用, 这里调用了函数 ...
 - 自建一个Java Spring MVC项目
			
用IDEA Intellij,本来创建的是SpringMVC项目,但是下载的时候,太慢了.所以还是用的Maven项目. 选择Maven 项目->Archetype->Web applica ...
 - Hadoop HDFS分布式文件系统设计要点与架构(转摘)
			
Hadoop简介:一个分布式系统基础架构,由Apache基金会开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力高速运算和存储.Hadoop实现了一个分布式文件系统(Ha ...
 - TensorFlowIO操作(一)----线程和队列
			
线程和队列 在使用TensorFlow进行异步计算时,队列是一种强大的机制. 为了感受一下队列,让我们来看一个简单的例子.我们先创建一个“先入先出”的队列(FIFOQueue),并将其内部所有元素初始 ...
 - html表格内容自动换行
			
有时候表格会因为内容多少忽大忽小的很烦人,在网上搜了下解决方案,效果不错哦,给大家分享下!首先介绍两个利器:table-layout:fixed //固定表格大小word-break:break-al ...