ListView 利用CursorAdapter 和 LoaderManager从数据库中获取数据
2015-10-31 13:10
525 查看
ListView从数据库获取数据并显示的一般方法就是直接将数据库的内容封装到List中,然后再用adapter将List内容显示在ListView中。但前几日偶然发现一种更灵活的方法,可以将数据库的内容加载到ListView中,即LoaderManager + CursorAdapter。这种方式可以把ListView绑定一个CursorAdapter然后可以将ListView的每一个item当做是数据库返回的cursor,即每个Item就是一个Cursor对象。然后用Cursor的get方法获取数据库的数据,直接通过Cursor来获取更新item,跳过了把Cursor中的数据封装。
CursorAdapter的每个item的显示是用newView(Context context, Cursor cursor, ViewGroup group)和bindView(View view, Context context, Cursor cursor),第一次创建视图先调用newView后调用bindView方法,后来再次创建时就只调用bindView方法。所以用CussorAdapter时是在newView中初始item的视图并return 这个视图,在bindView中负责视图更新的操作。
LoaderManager是一个加载器的管理器,一个LoaderManager可以管理一个或多个Loader,一个Activity或者Fragment只能有一个LoadManager。LoaderManager管理Loader的初始化,重启和销毁操作。通过使用getLoaderManager().initLoader(loader_id, null, LoaderCallbacks) 就可以初始化一个loader,LoaderManager的initLoader是不做任何事情的,它只绑定了一个LoaderCallbacks,具体的创建Loader的事情是由这个callback来做的。
LoaderCallbacks需要实现三个方法:
在loader创建loader的时候会调用onCreateLoader,然后当load数据结束的时候(第一次读取数据或者数据有改变的时候load数据)会调用onLoadFinished,而onLoaderReset只有在destory一个loader的时候才有可能调用。所以一般创建数据Cursor(CursorLoader)的工作是在onCreateLoader中做,在这里通CursorLoader cursorLoader = new CursorLoader(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)来查表并将CursorLoader返回,这样就创建了对这个数据源的监控,当数据源有数据变化的时候,就会自动调用了onLoadFinished函数了。一般adapter的数据更新都是在onLoadFinished()方法中调用adapter的changeCursor(data)方法来更新。
CursorAdapter的每个item的显示是用newView(Context context, Cursor cursor, ViewGroup group)和bindView(View view, Context context, Cursor cursor),第一次创建视图先调用newView后调用bindView方法,后来再次创建时就只调用bindView方法。所以用CussorAdapter时是在newView中初始item的视图并return 这个视图,在bindView中负责视图更新的操作。
LoaderManager是一个加载器的管理器,一个LoaderManager可以管理一个或多个Loader,一个Activity或者Fragment只能有一个LoadManager。LoaderManager管理Loader的初始化,重启和销毁操作。通过使用getLoaderManager().initLoader(loader_id, null, LoaderCallbacks) 就可以初始化一个loader,LoaderManager的initLoader是不做任何事情的,它只绑定了一个LoaderCallbacks,具体的创建Loader的事情是由这个callback来做的。
LoaderCallbacks需要实现三个方法:
在loader创建loader的时候会调用onCreateLoader,然后当load数据结束的时候(第一次读取数据或者数据有改变的时候load数据)会调用onLoadFinished,而onLoaderReset只有在destory一个loader的时候才有可能调用。所以一般创建数据Cursor(CursorLoader)的工作是在onCreateLoader中做,在这里通CursorLoader cursorLoader = new CursorLoader(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)来查表并将CursorLoader返回,这样就创建了对这个数据源的监控,当数据源有数据变化的时候,就会自动调用了onLoadFinished函数了。一般adapter的数据更新都是在onLoadFinished()方法中调用adapter的changeCursor(data)方法来更新。
public class SmsHistoryFragment extends ListFragment { private static final int LOADER_ID = 1; private LayoutInflater mInflater; private CursorAdapter mCursorAdapter; @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mInflater = LayoutInflater.from(getActivity()); initLoader(); setupListAdapter(); } private void setupListAdapter() { mCursorAdapter = new CursorAdapter(getActivity(),null,false) { @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { View view = mInflater.inflate(R.layout.item_sended_msg, parent, false); return view; } @Override public void bindView(View view, Context context, Cursor cursor) { TextView msg = (TextView) view.findViewById(R.id.id_tv_msg); FlowLayout fl = (FlowLayout) view.findViewById(R.id.id_fl_contacts); TextView fes = (TextView) view.findViewById(R.id.id_tv_fes); TextView date = (TextView) view.findViewById(R.id.id_tv_date); msg.setText(cursor.getString(cursor.getColumnIndex(SendedMsg.COLUMN_MSG))); fes.setText(cursor.getString(cursor.getColumnIndex(SendedMsg.COLUMN_FES_NAME))); long dateVal = cursor.getLong(cursor.getColumnIndex(SendedMsg.COLUMN_DATE)); date.setText(parseDate(dateVal)); String names = cursor.getString(cursor.getColumnIndex(SendedMsg.COLUMN_NAMES)); if (TextUtils.isEmpty(names)){ return; } fl.removeAllViews(); for (String name : names.split(":")){ addTag(name,fl); } } }; setListAdapter(mCursorAdapter); } DateFormat df =new SimpleDateFormat("yyyy-MM-dd HH:mm"); private String parseDate(long dateVal) { return df.format(dateVal); } private void addTag(String name, FlowLayout fl) { TextView tv = (TextView) mInflater.inflate(R.layout.tag, fl, false); tv.setText(name); fl.addView(tv); } private void initLoader() { getLoaderManager().initLoader(LOADER_ID, null, new LoaderManager.LoaderCallbacks<Cursor>() { @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { CursorLoader loader = new CursorLoader(getActivity(), SmsProvider.URI_SMS_ALL,null,null,null,null); return loader; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { if (loader.getId() == LOADER_ID); mCursorAdapter.swapCursor(data); } @Override public void onLoaderReset(Loader<Cursor> loader) { mCursorAdapter.swapCursor(null); } }); } }
相关文章推荐
- Mysql+Dos总结
- 指尖上的数据库之探囊取物
- mysql之TIMESTAMP(时间戳)用法详解
- Oracle 12C -- clone a non-cdb as a pdb
- 数据库in和exist的区别
- mysql系统库INFORMATION_SCHEMA,MySQL,TEST,mysql系统表的作用
- mysql 使用inet_aton和inet_ntoa处理ip地址数据
- 十款常见的开源数据库学习资料大汇总
- MyBatis动态SQL(2)
- MyBatis动态SQL(1)
- 数据库学习入门(转)
- PL/SQL显示行号和高亮当前行
- 数据库事务四大特性
- Mysql Event SCHEDULE Job 定时任务
- MySQL数据表的基本操作二:表结构查看、修改与表操作
- Rafy 框架 - 执行SQL或存储过程
- myql 数据库连接池
- Rafy 框架 - 为数据库生成注释
- 安装mysql
- 数据库-除