Android

您所在的位置:网站首页 多源数据库适配器是什么 Android

Android

2024-07-12 13:28| 来源: 网络整理| 查看: 265

如果大家看过我写的Android中SQLite的基本使用(二)这篇博客的话,应该知道,在实现数据库查询的时候,因为用了 rawQuery() 和 query(),而这两个方法返回的是一个 Cursor 的对象,我把 Cursor 转换成了我们熟悉的 list 集合,但这有些麻烦,其实 SQLite 给我们提供了 Cursor 中读取数据库数据的适配器,可以直接接收 Cursor 游标类型的数据源,分别是 SimpleCursorAdapter 和 CursorAdapter。这次我就来讲讲它们的使用。

数据库文件

关于数据库的创建,我在Android上SQLite的基本应用(一)中有详细的介绍,这里就不提了。

现在有一个数据库,里面有一张 PERSON 表,插入了30条数据,如下:

我们要在程序中使用它,自然得把它放到模拟器的 sdcard 目录下:

我们可以看到 info.db 确实被导入模拟器里了。当然我们也可以直接将文件拖进模拟器,这里只是讲下如何导入文件而已。

布局文件

因为我们要做的数据的适配,所以我们的 xml 中要有 listView:

activity_main.xml:

除此之外,既然是 listView,自然需要一个 item.xml:

常量类

Constant.java:

public class Constant { public static final String DATABASE_NAME = "info.db"; //数据库名称 public static final int DATABASE_VERSION = 1; //数据库版本 public static final String TABLE_NAME = "person"; //表名 public static final String _ID = "_id"; public static final String NAME = "name"; public static final String AGE = "age"; } SimpleCursorAdapter

MainActivity.java:

public class MainActivity extends AppCompatActivity { private ListView mListView; private SQLiteDatabase db; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (ListView) findViewById(R.id.lv); //1.获取数据库查询的数据源 String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "info.db"; db = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY); Cursor cursor = db.rawQuery("select * from " + Constant.TABLE_NAME, null); //2.将数据源数据加载到适配器中 SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.item, cursor, new String[]{Constant._ID, Constant.NAME, Constant.AGE}, new int[]{R.id.tv_id, R.id.tv_name, R.id.tv_age}, SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); //3.将适配器的数据加载到控件 mListView.setAdapter(adapter); } }

ListView 是一个适配器控件,使用适配器控件一共有三步:

从数据库得到数据源把数据源的数据加载到适配器把适配器的数据展示到控件中 第一步

既然要从数据库取数据,自然要有一个 SQLiteDatabase 的对象,在这里我用了 openDatabase() 这个方法。

openDatabase(String path, CursorFactory factory, int flags)

path:表示当前打开数据库存放路径。获取 sdcard 目录的方法相信大家都不陌生了吧,如果在其它目录,只要依样画葫芦找到路径即可。 factory:游标工厂,指定为空即可。 flags 表示打开数据库的操作模式,可读可写。这里只读即可。

打开了数据库,自然要获取数据,这里用 rawQuery 或者 query 都可以,这样我们就得到了 Cursor 游标。

第二步

有了数据源,就要把它放到适配器里。SimpleCursorAdapter 与 SimpleAdapter 原理相似。

SimpleAdapter 是一个 list 集合存放着 Map 键对,通过 key 将每个 Map 传入 ListView 的 item 里。

Cursor 我们可以看作一张表,把每行的数据放到 ListView 的每个 item 里去,SimpleCursorAdapter 就是这样的工作原理。

SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags)

context:上下文 layout:表示适配器控件中每项item对应的 id cursor:表示cursor数据源 from:表示cursor中数据表字段的数组 to:表示展示字段对应值的控件资源 id flags:设置适配器的标记,设置观察者模式,观察者模式就是有一个观察者观察适配器的数据是否改变,改变就提醒。

第三步

将适配器与 ListView 绑定,这里都是一样的。使用SimpleCursorAdapter 的时候有一个要注意的是,它只识别 _id 为主键,如果你要用 SImpleCursorAdapter 的话,你的主键得是 _id,否则会报错。

现在就可以运行了,不过我们当然不能忘记,我们既然访问了 SD 卡,读写的权限自然不能不加,这里就不写出来啦。大家也要注意如果你的是Android6.0 以上的机子你就要手动添加权限了。

CursorAdapter

写 CursorAdapter 在获取到数据源 Cursor 时都是一样的,因为 CursorAdapter 是抽象类,所以不能像 SimpleCursorAdapter 一样去 new 出实例,在这里我使用内部类来继承 CursorAdapter。

CursorAdapterActivity.java:

public class CursorAdapterActivity extends AppCompatActivity { private ListView lv; private SQLiteDatabase db; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv = (ListView) findViewById(R.id.lv); String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "info.db"; db = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY); Cursor cursor = db.rawQuery("select * from " + Constant.TABLE_NAME, null); MyCursorAdapter adapter = new MyCursorAdapter(this, cursor, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); lv.setAdapter(adapter); } public class MyCursorAdapter extends CursorAdapter{ public MyCursorAdapter(Context context, Cursor c, int flags) { super(context, c, flags); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { View view = LayoutInflater.from(CursorAdapterActivity.this).inflate(R.layout.item, null); return view; } @Override public void bindView(View view, Context context, Cursor cursor) { TextView tv_id = (TextView) view.findViewById(R.id.tv_id); TextView tv_name = (TextView) view.findViewById(R.id.tv_name); TextView tv_age = (TextView) view.findViewById(R.id.tv_age); tv_id.setText(cursor.getInt(cursor.getColumnIndex(Constant._ID)) + ""); tv_name.setText(cursor.getString(cursor.getColumnIndex(Constant.NAME))); tv_age.setText(cursor.getInt(cursor.getColumnIndex(Constant.AGE)) + ""); } } }

CursorAdapter 会让我们必须有三个函数,构造方法自不必说,需要我们重写的就是 newView() 和 bindView()。

newView:并不是每次都被调用的,它只在实例化的时候调用,数据增加的时候也会调用,但是在重绘(比如修改条目里的 TextView 的内容)的时候不会被调用。表示创建适配器控件中每个item对应的对象

View newView(Context context, Cursor cursor, ViewGroup parent)

context:上下文 cursor:数据源 cursor 对象 parent:当前 item 的父布局 最后返回每项的 item 的 view 对象。

bindView:在绘制 Item 之前一定会调用 bindView 方法,它在重绘的时候也同样被调用。通过newView()方法确定了每个item展示的view对象,在bindView中对布局中的控件进行填充。

void bindView(View view, Context context, Cursor cursor)

view:由 newView() 返回的每个 view 对象 context:上下文 cursor:数据源 cursor 对象

在这里稍微多提一下,CursorAdapter 还有一个重要的方法 changeCursor (Cursor cursor),调用此方法后会把当前的 Cursor 置为新传过来的 Cursor,把原来的 Cursor 返回去并关掉。

当我们的Cursor变化时调用此方法 adapter.changeCursor(cursor),它的功能类似于 adapter.notifyDataSetChanged() 方法。

我们在配置文件把 CursorAdapterActivity 换掉 MainActivity,再来运行一下。

因为这两种不过是适配器的不同,所以当然不会有什么问题。如果我们只是想要将数据库的数据展示出来,那就可以不用 Cursor 转 List 创建实体类的方法,用SimpleCursorAdapter 和 CursorAdapter,将 Cursor 获取后直接放到我们的适配器控件当中,这样就使我们的代码更简洁,使用起来也更方便。

结束语:本文仅用来学习记录,参考查阅。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3