CursorLoaderを使ってデータを読み込み、CursorAdapterをカスタマイズしたアダプターを使いListViewに表示する
以前のエントリで「ContentProvierとCursorLoaderとFragmentを使ったサンプルを作ってみた」
というものを書きました。
その時にListViewにセットしたアダプターは「SimpleCursorAdapter」という便利なクラスを利用したのですが、
リストを色々とカスタマイズしたいこともあると思います。
そこで、Cursorを利用してデータをセットすることができる「CursorAdapter」クラスを拡張して利用するように書き換えてみました。
Database周りは上記エントリのソースと変わりません。
上記のエントリではリストをクリックするとサブ画面が表示されましたが、このサンプルではサブ画面はナシです。
githubのソースはこちらです。ダウンロードはこちらです。
データを読み込む側はCursorLoaderを使用してDBのデータをCursorに取得したらonLoadFinished()が実行されますので
swapCursor() メソッドを使用してCursorをcloseせずに新しいデータに置き換えます。
@Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { // 画面を更新する mAdapter.swapCursor(cursor); mAdapter.notifyDataSetChanged(); }
アダプター側ではnewView()メソッドでListViewの行のViewを生成し、
bindView()メソッドで先程生成したviewを使いまわしつつデータをセットしていく感じです。
実行イメージはこんな感じ。
アダプターのソースはこんな感じ。
package com.example.myexamcustomcursorloader; import android.content.Context; import android.database.Cursor; import android.support.v4.widget.CursorAdapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.example.myexamcustomcursorloader.data.PlaceManager; /** * CursorAdapterを拡張してCursorの内容をListViewにセットします * * @author sakura */ public class ListAdapter extends CursorAdapter { private LayoutInflater mInflater; class ViewHolder { TextView id; TextView place_id; TextView place; TextView url; } /** * @param context * @param c * @param autoRequery */ public ListAdapter(Context context, Cursor c, boolean autoRequery) { super(context, c, autoRequery); mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } /** * @inheritDoc */ @Override public void bindView(View view, Context context, Cursor cursor) { // Viewを再利用してデータをセットします ViewHolder holder = (ViewHolder) view.getTag(); // Cursorからデータを取り出します final int id = cursor.getInt(cursor.getColumnIndexOrThrow(PlaceManager.Place.KEY_ID)); final String placeID = cursor.getString(cursor .getColumnIndexOrThrow(PlaceManager.Place.KEY_PLACE_ID)); final String place = cursor.getString(cursor .getColumnIndexOrThrow(PlaceManager.Place.KEY_PLACE)); final String url = cursor.getString(cursor .getColumnIndexOrThrow(PlaceManager.Place.KEY_URL)); // 画面にセットします holder.id.setText("id=" + String.valueOf(id)); holder.place_id.setText("place_id=" + placeID); holder.place.setText(place); holder.url.setText(url); } /** * @inheritDoc */ @Override public View newView(Context context, Cursor cursor, ViewGroup viewGroup) { // 新しくViewを作ります final View view = mInflater.inflate(R.layout.list_item, null); ViewHolder holder = new ViewHolder(); holder.id = (TextView) view.findViewById(R.id.id); holder.place_id = (TextView) view.findViewById(R.id.place_id); holder.place = (TextView) view.findViewById(R.id.place); holder.url = (TextView) view.findViewById(R.id.url); view.setTag(holder); return view; } }
データ読み込み側のソースはこんな感じ。
package com.example.myexamcustomcursorloader; import android.database.Cursor; import android.os.Bundle; import android.support.v4.app.ListFragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.example.myexamcustomcursorloader.data.PlaceManager; /** * CursorLoaderを使ってテーブルのデータをListViewに表示します * * @author sakura */ public class PlaceListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> { private ListAdapter mAdapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.list, container, false); return view; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // adapterをセットします mAdapter = new ListAdapter(getActivity(), null, true); setListAdapter(mAdapter); mAdapter.notifyDataSetChanged(); // Loaderの初期化 getLoaderManager().initLoader(0, null, this); } @Override public void onDestroyView() { super.onDestroyView(); // Loaderの廃棄 getLoaderManager().destroyLoader(0); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle bundle) { // CursorLoader生成(検索条件の指定) // ここでは全件取得 return new CursorLoader(this.getActivity(), PlaceManager.Place.CONTENT_URI, null, null, null, null); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { // 画面を更新する mAdapter.swapCursor(cursor); mAdapter.notifyDataSetChanged(); } @Override public void onLoaderReset(Loader<Cursor> loader) { mAdapter.swapCursor(null); } }