Loader监听数据源的变化
步骤:
1.新建一个继承SQLiteOpenHelper的帮助类
2.在MainActivity中定义LoaderManager和SimpleCursorAdapter
3.按顺序重写如下方法:initLoader来启动
onCreateLoader->onStartLoading(forceLoad启动时强制加载)->loadInBackground->onLoadFinished(adapter.swapCursor(data))->onLoaderReset(adapter.swapCursor(null))
*manager.restartLoader()数据改变时立刻加载
public class DBHelper extends SQLiteOpenHelper {
public static final String USERTABLE = "usertable";
private static final String DBNAME = "QF.DB";
private static final int CURRENTVERSION = 1;
public DBHelper(Context context) {
super(context, DBNAME, null, CURRENTVERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + USERTABLE + "(_id INTEGER PRIMARY KEY AUTOINCREMENT" +
",USERNAME,NICKNAME);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
/**
* Loader:自动监听数据源是否发生变化
*/
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> { private static SQLiteDatabase db;
private DBHelper dbHelper;
private SimpleCursorAdapter adapter;
private LoaderManager manager; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new DBHelper(this);
db = dbHelper.getReadableDatabase();
ListView listView = (ListView) findViewById(R.id.lv);
// 1.获得一个Loader管理器
manager = getSupportLoaderManager();
//2.初始化Loader
//1.Loader的唯一标识符
//2.初始化Loader时传递的参数
//3.Loader的回调
manager.initLoader(1, null, this);
//最后一个参数表示当数据源发生改变时,Cursor能够立马感知到数据源发生变化
adapter = new SimpleCursorAdapter(this,
R.layout.listview_item, null, new String[]{"USERNAME"}, new int[]{R.id.username},
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
listView.setAdapter(adapter);
} //当Loader创建时回调
//1.Loader的id
//2.初始化Loader的参数
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Log.d("lenve", "onCreateLoader: " + Thread.currentThread());
return new MyLoader(this);
} //当异步加载完成时调用该方法
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
Log.d("lenve", "onLoadFinished: " + Thread.currentThread());
//交换Cursor
adapter.swapCursor(data);
} //当由于Loader重置导致Cursor失效时,调用该方法
@Override
public void onLoaderReset(Loader<Cursor> loader) {
Log.d("lenve", "onLoaderReset: " + Thread.currentThread());
adapter.swapCursor(null);
} public void addData(View view) {
ContentValues values = new ContentValues();
values.put("USERNAME", "李四i");
db.insert(DBHelper.USERTABLE, null, values);
//重启Loader
manager.restartLoader(1, null, this);
} static class MyLoader extends AsyncTaskLoader<Cursor> { public MyLoader(Context context) {
super(context);
} //在后台线程执行
@Override
public Cursor loadInBackground() {
Log.d("lenve", "loadInBackground: " + Thread.currentThread());
Cursor cursor = db.rawQuery("SELECT * FROM " + DBHelper.USERTABLE, null);
//在这里放回一个Cursor,该Cursor最终被onLoadFinished()方法接收到
return cursor;
} //开始加载时调用
@Override
protected void onStartLoading() {
super.onStartLoading();
Log.d("lenve", "onStartLoading: " + Thread.currentThread());
//第一次需要强制加载
forceLoad();
}
}
}
其中,适配器可以定义一个继承CursorAdapter的类,和baseAdapter的道理类似;且cursorAdapter的两个方法newView和bindView相当于BaseAdapter的getView方法的拆分
/**
* newView和bindView相当于BaseAdapter中的getView()方法
*/
public class MyAdapter extends CursorAdapter {
private LayoutInflater inflater; public MyAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
inflater = LayoutInflater.from(context);
} //初始化View
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = inflater.inflate(R.layout.listview_item, null);
ViewHolder holder = new ViewHolder();
holder.username = (TextView) view.findViewById(R.id.username);
view.setTag(holder);
return view;
} //给View上的控件绑定事件
//cursor.getColumnIndex("USERNAME")获取USERNAME字段的下标
@Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder) view.getTag();
holder.username.setText(cursor.getString(cursor.getColumnIndex("USERNAME")));
} class ViewHolder {
TextView username;
}
}
Loader监听数据源的变化的更多相关文章
- 详解vuex结合localstorage动态监听storage的变化
这篇文章主要介绍了详解vuex结合localstorage动态监听storage的变化,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 需求:不同组件间共用同一数据,当一个 ...
- HTML5 oninput实时监听输入框值变化的完美方案
在网页开发中经常会碰到需要动态监听输入框值变化的情况,如果使用 onkeydown.onkeypress.onkeyup 这个几个键盘事件来监测的话,监听不了右键的复制.剪贴和粘贴这些操作,处理组合快 ...
- 【转载】实时监听输入框值变化的完美方案:oninput & onpropertychange
oninput 是 HTML5 的标准事件,对于检测 textarea, input:text, input:password 和 input:search 这几个元素通过用户界面发生的内容变化非常有 ...
- 实时监听输入框值变化:oninput & onpropertychange
结合 HTML5 标准事件 oninput 和 IE 专属事件 onpropertychange 事件来监听输入框值变化. oninput 是 HTML5 的标准事件,对于检测 textarea, i ...
- js/jquery 实时监听输入框值变化的完美方案:oninput & onpropertychange
(1) 先说jquery, 使用 jQuery 库的话,只需要同时绑定 oninput 和 onpropertychange 两个事件就可以了,示例代码: $('#username').bin ...
- JS 获取和监听屏幕方向变化(portrait / landscape)
移动设备的屏幕有两个方向: landscape(横屏)和portrait(竖屏),在某些情况下需要获取设备的屏幕方向和监听屏幕方向的变化,因此可以使用Javascript提供的 MediaQueryL ...
- 实时监听输入框值变化的完美方案:oninput & onpropertychange
实时监听输入框值变化的完美方案:oninput & onpropertychange: 网址:http://www.cnblogs.com/lhb25/archive/2012/11/30/o ...
- 监听EditText的变化
http://liangruijun.blog.51cto.com/3061169/729505 之前博客上的有关EditText的文章,只是介绍EditText的一些最基本的用法,这次来深入学习一下 ...
- input 即时搜索 监听输入值的变化
在 Web 开发中经常会碰到需要动态监听输入框值变化的情况,如果使用 onkeydown.onkeypress.onkeyup 这个几个键盘事件来监测的话,监听不了右键的复制.剪贴和粘贴这些操作,处理 ...
随机推荐
- div 只显示两行超出部分隐藏
; -webkit-box-orient: vertical;line-height: 26px } <td rowspan="2" colspan="2" ...
- UE4的AI学习(2)——官方案例实例分析
官方给出的AI实例是实现一个跟随着玩家跑的AI,当玩家没有在AI视野里时,它会继续跑到最后看到玩家的地点,等待几秒后如果仍然看不到玩家,则跑回初始地点.官方的案例已经讲得比较详细,对于一些具体的函数调 ...
- luogu P4744 [Wind Festival]Iron Man
再次感谢题解区大佬的指点 规定\(pre[i]\)表示前缀\(i\)的前缀和,\(sum[i][j]\)表示区间\([i,j]\)之和 令\(f[i][j]\)表示前i个数选出j段的最大值,\(g[i ...
- Flask最强攻略 - 跟DragonFire学Flask - 第五篇 做一个用户登录之后查看学员信息的小例子
需求: 1. 用户名: oldboy 密码: oldboy123 2. 用户登录成功之后跳转到列表页面 3. 失败有消息提示,重新登录 4.点击学生名称之后,可以看到学生的详细信息 后端: from ...
- TCP传输协议
TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接,四次挥手断开连接. 三次握手 是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接建立成功.在so ...
- Python提示AttributeError 或者DeprecationWarning: This module was deprecated解决方法
Python提示AttributeError 或者DeprecationWarning: This module was deprecated解决方法 在使用Python的sklearn库时,发现sk ...
- shiro自定义realm认证(五)
上一节介绍了realm的作用: realm:需要根据token中的身份信息去查询数据库(入门程序使用ini配置文件),如果查到用户返回认证信息,如果查询不到返回null.token就相当于是对用户输入 ...
- linux挂载硬盘以及卸载硬盘
1.在vmware添加硬盘 2.输入fdisk -l 查看新增加的硬盘 3.分区初始化 4.指定文件系统 5.修改fstab文件 fstab: 6.刷新验证 mount -a 挂载定义在/etc/fs ...
- 如何利用github打造个人博客专属域名(文字版本)
1. 前言 此篇文章仅限于记录,不适合作为教程使用. 2. 步骤 2.1 先决条件 有github账号,有个人域名(可在万网购买),电脑本地安装有git环境 2.2 在github新建仓库.例如我的g ...
- 转:10分钟了解JS堆、栈以及事件循环的概念
https://juejin.im/post/5b1deac06fb9a01e643e2a95?utm_medium=fe&utm_source=weixinqun 前言 其实一开始对栈.堆的 ...