2012年11月4日日曜日

CursorAdapterの基本

CursorAdapterって何

Androidはちょっと大容量のデータをメモリにおくだけで不可避なOutOfMemoryエラーが発生する。

ともするとListViewなどで大量のデータを列挙をしたい場合(たとえばTwitterのタイムラインとか)だと、

メモリに保持しておく仕様だと表示する件数に限界が出てくる。列挙するデータの中に画像などが含まれたら余計にその件数は圧迫される。

で、SQLiteにデータを保持させ、そこから必要なときだけ動的にデータをSelectし、バインドさせる方法がある。

そうすることによりメモリの圧迫を抑え、膨大な件数を早い処理で画面に表示させることが出来る。

それを実現するクラスがCursorAdapterとなる。

勿論使い方は基本的に今までのAdapterと変わらない。


SimpleCursorAdapter

CursorAdapterを簡単に実装できるクラスとしてSimpleCursorAdapterがある。

SimpleCursorAdapter (Context context, int layout, Cursor c, String[] from,
int[] to)
context:コンテキスト

layout:表示するレイアウトID

cursor:SQLiteからSELECTしたCursor

from:Cursorのカラム名

to:バインドする先のViewID


が引数となっており、fromとtoのlengthは同じでなければならず、お互いが対応関係になっている。

すなわちfromで1番目に指定したカラム名の値がtoで1番目に指定したViewにバインドされる形で反映される。

これはCursorのもつ値をそのまま表示する際にはとても楽であるけど、変換や処理をかませるときには使いにくいし、

Spinnerのような二つのレイアウト(DropDown時と通常時)を持つ場合も使いにくい。


ちなみにSpinnerでそのままSimpleCursorAdapterを使う場合は、

setDropDownViewResource(resourceId)で別にレイアウトIDを指定してあげる。

コンストラクタで指定したfrom、toの関係にDropDownViewも合わせなければならないので余計に面倒。


CursorAdapter拡張

んで、SimpleCursorAdapterの大元のCursorViewを拡張する。

CursorAdapterのCursorAdapterたる部分は以下二つのメソッドのOverride。

@Override
public void bindView(View view, Context context, Cursor cursor) {
//newViewで作ったViewが引数として渡ってくるので、それに応じてバインドする
TextView tv = (TextView)view.findViewById(R.id.text);
tv.setText(cursor.getString(cursor.getColumnIndex(columnName)));
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
//初めて表示されるときに呼ばれる。ここでレイアウトを定義。
View v = context.getLayoutInflater().inflate(R.layout.layout_id,
parent)
return v;
}

Spinnerの場合は同じように以下二つも拡張

getDropDownView(int position, View convertView, ViewGroup parent)

newDropDownView(Context context, Cursor cursor, ViewGroup parent)


なお、Adapeterの保持データが変更したときにそれを画面に反映させるnotifyDataSetChanged()だが、

CursorAdapterの場合はAdapterからgetCursor().requery()を呼ぶことで、内部でnotifyDataSetChanged()が呼ばれる。


やっぱり使いにくい面も

Curosrをもとに列挙させるということは、素直に作るとイレギュラーな行を途中で挿入できないということ。

だからListViewの途中でヘッダー的なレイアウトを差し込むだとかは難しい。

単純に大量のデータを列挙する、という目的には有効だが、列挙する行が増減するような複雑な処理はできないの??

0 件のコメント:

コメントを投稿