Android Loader的基本知识前面几篇博客已经涉及很多,接下来这篇博客将会结合一个实际Demo来描述Loader的使用,该Demo是Contacts 联系人,自定义ContentProvider的内容,提供Uri,在显示联系人列表出使用的是Cursor 的 contentResolver.query 方法,在搜索联系人部分用到了CursorLoader,下面结合这个Demo 来描述Loader的使用。
Demo 截图如下:
下面对该Demo的各个函数进行详解。搜索界面的代码是一个由Fragment组成的Activity,fragment 代码如下:
package com.uppowerstudio.chapter5.phonebook; import android.app.ListFragment; import android.app.LoaderManager; import android.content.CursorLoader; import android.content.Loader; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.widget.SearchView; import android.widget.SearchView.OnQueryTextListener; import android.widget.SimpleCursorAdapter; import com.uppowerstudio.chapter5.phonebook.database.Constants; public class CursorLoaderListFragment extends ListFragment implements Constants, OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> { SimpleCursorAdapter mAdapter; String mCurFilter; @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); //设置包含菜单项 setHasOptionsMenu(true); mAdapter = new SimpleCursorAdapter(getActivity(), R.layout.list_row, null, new String[] { "contact_name", "phone_number" }, new int[] { R.id.list_item_contact_name, R.id.list_item_contact_phone }, 0); setListAdapter(mAdapter); //初始化Loader ,Loader的ID 为0 getLoaderManager().initLoader(0, null, this); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // TODO Auto-generated method stub super.onCreateOptionsMenu(menu, inflater); //添加查找菜单栏 MenuItem item = menu.add("Search"); item.setIcon(android.R.drawable.ic_menu_search); item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); SearchView sv = new SearchView(getActivity()); sv.setOnQueryTextListener(this); item.setActionView(sv); } @Override public boolean onQueryTextSubmit(String query) { // TODO Auto-generated method stub return true; } @Override public boolean onQueryTextChange(String newText) { // TODO Auto-generated method stub mCurFilter = !TextUtils.isEmpty(newText) ? newText : null; getLoaderManager().restartLoader(0, null, this); return true; } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { // TODO Auto-generated method stub Uri baseUri; if (mCurFilter != null) { baseUri = Uri.withAppendedPath(Constants.CONTENT_URI, Uri.encode(mCurFilter)); } else { baseUri = Constants.CONTENT_URI; } return new CursorLoader(getActivity(), baseUri, null, null, null, COLUMN_ID); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // TODO Auto-generated method stub mAdapter.swapCursor(data); } @Override public void onLoaderReset(Loader<Cursor> loader) { // TODO Auto-generated method stub mAdapter.swapCursor(null); } }
下面结合这个 Demo 对 CursorLoader进行详解。
首先,我这里编写的查找联系人的布局是一个activity加fragment,在fragment的onActivityCreated()方法中,我们先初始化Loader,
getLoaderManager().initLoader(0, null, this);
该函数中有3个参数,第一个是新建的Loader的ID,这里为0,第二个是Bunder类型的数据,这里设置为null,第三个是this,表示回调本身
@Override public boolean onQueryTextChange(String newText) { // TODO Auto-generated method stub mCurFilter = !TextUtils.isEmpty(newText) ? newText : null; getLoaderManager().restartLoader(0, null, this); return true; }
@Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { // TODO Auto-generated method stub Uri baseUri; if (mCurFilter != null) { baseUri = Uri.withAppendedPath(Constants.CONTENT_URI, Uri.encode(mCurFilter)); } else { baseUri = Constants.CONTENT_URI; } return new CursorLoader(getActivity(), baseUri, null, null, null, COLUMN_ID); }
@Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // TODO Auto-generated method stub mAdapter.swapCursor(data); }
@Override public void onLoaderReset(Loader<Cursor> loader) { // TODO Auto-generated method stub mAdapter.swapCursor(null); }
@Override public boolean onQueryTextSubmit(String query) { // TODO Auto-generated method stub return true; }