基于Fragment,Loader,Actionbar的几个好文章转载 3

本文介绍如何使用Android的Loader实现ListView的异步加载功能,并通过示例展示了如何结合SQLite、ContentProvider及CursorAdapter来自动更新ListView的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  Android 3.0 sdk,引入了很多新api,比如Loader。和Fragment类似(编写兼容android1.6的fragment),该api也可在Android 1.6以上版本执行。

        以下介绍如何编写Loader,实现对ListView的异步加载。效果如图:

7.png

2011-7-13 17:16:54 上传
下载附件 (41.69 KB)


       示例中有一个后台线程每隔3秒更新数据库的长江记录,将记录改为“长江”或“Long River”。ListView无需监控数据库变化,基于Loader,会自动更新。实际上这里面是观察者模式,无非是系统自带了,只需调用即可,无需自己构造观察者。


       这个示例也是完整的sqlite+content provider+cursor adapter+listview+loader组合示例。


       编写前的准备类似编写兼容android1.6的fragment,需要导入jar包。

       另外,2.3以前的Activity类没有提供一些Loader的帮助方法,需要让自己的Activity实现类继承FragmentActivity:


java代码:

  1. public class ListViewActivity extends FragmentActivity
复制代码

        本示例是在在视图显示中使用Theme基础上实现的。
        Activity类和RiverContentProvider类做了修改。
        Activity类:

java代码:
  1. public class ListViewActivity extends FragmentActivity {

  2. private ListView riverListView;

  3. private SimpleCursorAdapter adapter;
  4. /** Called when the activity is first created. */

  5. @Override
  6. public void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.main);

  9. initLoader();
  10. setRiverListViewAdapter();
  11. }

  12. private void initLoader() {
  13. getSupportLoaderManager().initLoader(0, null,
  14. new LoaderCallbacks<Cursor>() {

  15. @Override
  16. public Loader<Cursor> onCreateLoader(int id, Bundle args) {
  17. Log.d("list", "on create loader");
  18. CursorLoader cursorLoader=new CursorLoader(ListViewActivity.this,
  19. RiverContentProvider.CONTENT_URI, new String[] {
  20. RiverContentProvider._ID,
  21. RiverContentProvider.NAME,
  22. RiverContentProvider.INTRODUCTION },
  23. null, null, null);
  24. //cursorLoader.setUpdateThrottle(1000);
  25. return cursorLoader;
  26. }

  27. @Override
  28. public void onLoadFinished(Loader<Cursor> loader,
  29. Cursor cursor) {
  30. Log.d("list", "on loader finished");
  31. adapter.swapCursor(cursor);
  32. }

  33. @Override
  34. public void onLoaderReset(Loader<Cursor> loader) {
  35. Log.d("list", "on loader reset");
  36. adapter.swapCursor(null);
  37. }
  38. });
  39. }

  40. private void setRiverListViewAdapter() {
  41. riverListView = (ListView) this.findViewById(R.id.riverList);

  42. Cursor cursor = managedQuery(RiverContentProvider.CONTENT_URI, null,
  43. null, null, null);
  44. adapter = new SimpleCursorAdapter(this, R.layout.row, cursor,
  45. new String[] { RiverContentProvider.NAME,
  46. RiverContentProvider.INTRODUCTION }, new int[] {
  47. R.id.riverName, R.id.riverIntroduction }, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
  48. riverListView.setAdapter(adapter);
  49. }
复制代码

       主要是增加了initLoader方法。这里主要是实现了LoaderCallbacks接口。其中:

       onCreateLoader,在创建activity时跟着onCreate会调用一次
        onLoadFinished,每次改变和Loader相关的数据库记录后会调用一次
        onLoaderReset,在关闭Activity时调用,释放资源


        然后,在Content provider中,要调用类似观察者模式中通知的方法,即,在update方法中通知观察者记录改变,在query方法中注册观察者,这样通知来了可接收并处理。

         update方法:

java代码:

  1. @Override
  2. public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
  3. int returnValue = database.update("rivers", values, selection, selectionArgs);
  4. getContext().getContentResolver().notifyChange(uri, null);
  5. return returnValue;
  6. }
复制代码

       query方法:

java代码:

  1. public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){
  2. Cursor cursor = database.query("rivers", projection, selection, selectionArgs, null, null, sortOrder);
  3. cursor.setNotificationUri(getContext().getContentResolver(), uri);
  4. return cursor;
  5. }
复制代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值