您的位置:首页 > 数据库

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)方法来更新。

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);
}
});
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: