现在的位置: 首页 > 综合 > 正文

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

2013年01月12日 ⁄ 综合 ⁄ 共 2933字 ⁄ 字号 评论关闭

  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. }

复制代码

【上篇】
【下篇】

抱歉!评论已关闭.