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 件のコメント:
コメントを投稿