Androidのアプリ開発関連のブログ

MatrixCursorを使ってListViewを更新することにした

前回のListViewの内容とデータベースの整合が取れてなかった件で、完全に理解できてないのだが、
setViewBinderで変更時イベントを設定してデータベースの更新をして、行追加は1行目に挿入されるってやってた。
そうすると、行を追加した際は表示済みの行のViewBinderは再発動せずに中のEditTextの文字列が変わるだけ。
って感じなんだと思う。
だからその時にTextWatcherが変更を検知しちゃって予期せぬ行のデータベースが変更されてたような・・・

で、その方法で解決できないこともないと思うのだが、解決するために無駄にコード量増えちゃいそうだし、
そもそも本来細かくDB更新すべきじゃないし、TextWatcherは使わないでアプリ終了時とかにまとめて更新することにした。


いつもはSimpleAdapterを使っててSimpleCursorAdapterは初めて使った気がするのだが、
データベースの更新が不要ならSimpleCursorAdapterではなくSimpleAdapterでいいんでね?
と思ったのだが、初めて気づいたがSimpleAdapterって作成した後に行を追加する機能が無いような・・・
SimpleCursorAdapterにしろ何にしろ、ListViewは更新がやたら不便なような・・・

今回は結局SimpleCursorAdapterでSQLiteDatabaseからselectした内容を表示して、
行追加の際はListViewに表示されている行のViewGroupを1行づつ取り出して、各Viewの状態からデータを取得。
取得できたデータを元にMatrixCursorを作成。
CursorAdapter.changeCursor()で新しいMatrixCursorと交換。
という方法に決めた。
うまく行ったはず。


なのだが、変更作業中にListViewが更新されない症状が発生して4時間ほどハマった。
原因は、ListViewの子要素からMatrixCursorを作成する処理を作ったが、
新しく挿入すべき行を挿入する処理を入れ忘れてたw
単にchangeCursor()するだけで更新される。

ちょっと開発やったのだが・・・

今日は年末に考えてたチェックリストの制作をちょっとやったのだが、
一応入力できる感じにはすぐ作れたが、変更して再起動すると何かおかしい事に・・・

今のところはEditTextとCheckBoxが並んだListViewで、
データ用のArrayListとか用意せずにSimpleCursorAdapterを使って直接表示したので変更が発生したら即時記録したかったので、
setViewBinderでListView内の各Viewにイベントを設定して保存するようにしたのだが、update対象の行がおかしいことになっているような・・・


今日は原因の究明は諦めたが、setViewBinderのsetViewValueが、
public boolean setViewValue(View view,Cursor cursor, int columnIndex){}
と、View,Cursor,columnIndexしかくれないのね。
columnIndexはSQLiteクエリのselect結果1行分のうち対象データのカラムの番号で0からになると思われるので、
primary keyもselectしておいて、primary keyが先頭のクエリなら、
cursor.getInt(0);
でキーが取得できるつもりでいるんで、
final intにしておいてupdateクエリの際にwhereで行指定したんだが、
なんかおかしな事なって、エラーにはならんしデバックも難しかった。
insertとupdateの発生する箇所と再起動の際に、細かくdbファイルを覗けば究明できるかな?


UIはシンプルにするんで、この問題が解決すれば時間はかからなそう。