かなり初心者で、ここに私の最初の投稿です。カスタム baseadapter を使用してリストビューを設定する 2.3.3 で正常に動作するアプリがあります。問題は、Android 3/4 で廃止された startManagingCursor と requery を使用していることです。
私はsqliteと、すべてのクエリを保持するデータベースアダプターと、アクティビティからパラメーターを渡すためのプライベートメソッドを使用しています。アイテムを長押しするか、アイテムをクリックして新しいアクティビティで開き、リストが正常に更新されると、リストを更新できます。
メイン UI でこれらのタイプの操作を実行するべきではないことは理解していますが、cursorloader を理解するのに苦労しています。それは必要ですか? 別のスレッドで実行するには、asynctask のような別のものを使用する必要があります。これがどのように組み合わされるのか理解できません。正しい方向への助けをいただければ幸いです。ありがとう。
これは、最も関連性の高いコードが MyActivity からのものであると私が思うものの小さなサンプルです
public class MyActivity extends ListActivity {
private MyDBAdapter dbAdapter;
private MyCursorAdapter mCursorAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylayout);
this.dbAdapter = new MyDBAdapter(this);
this.dbAdapter.open();
queryParams = getQueryParams();
queryDB(queryParams);
}
private void queryDB(String qParams) {
Cursor c = this.dbAdapter.fetchQuery(qParams);
startManagingCursor(c);
this.mCursorAdapter = new MyCursorAdapter(this, c);
setListAdapter(this.mCursorAdapter);
this.mCursorAdapter.changeCursor(c);
}
public void updateStatus(long paramLong, int paramInt) {
Cursor c = this.dbAdapter.updateDBStatus(paramLong, paramInt);
startManagingCursor(c);
this.mCursorAdapter.changeCursor(c);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (this.dbAdapter != null) {
this.dbAdapter.close();
}
}
}
および CursorAdapter
public class MyCursorAdapter extends CursorAdapter {
public MyCursorAdapter(Context cxt, Cursor cur, int flags) {
super(cxt, cur);
mContext = cxt;
mLayoutInflater = LayoutInflater.from(cxt);
}
@Override
public View newView(Context cxt, Cursor cur, ViewGroup parent) {
View vw = mLayoutInflater.inflate(LAYOUT_ID, parent, false);
return vw;
}
@Override
public void bindView(View vw, Context cxt, Cursor cur) {
int id = cur.getInt(cur.getColumnIndexOrThrow("_id"));
String name = cur.getString(cur.getColumnIndexOrThrow("name"));
int completed = cur.getInt(cur.getColumnIndexOrThrow("completed"));
TextView tv = (TextView) vw.findViewById(R.id.name);
if(completed == 1) {
tv.setTextColor(0x7fffffff);
} else {
tv.setTextColor(0xffffffff);
}
}
}
================編集==================
私は startManagingCursor() と requery() を削除し、互換性パッケージから import android.support.v4.widget.CursorAdapter を追加しました。さまざまな場所から複数の呼び出しがあったため、プライベート Cursor mCursor を作成し、this.mCursorAdapter.changeCursor(mCursor) を使用して更新しました。
現在、これは次の点を除いてほとんど機能します。
- メインUIで実行されるため、これを行うべきではありません
- カーソルを閉じる方法は、アプリの設定方法によって異なります
私の場合、カーソルを閉じることができません。そうしないと、リストビューが空になります。onDestroy() で閉じると、実行が保証されません。また、onBackPressed() で閉じると、新しいカーソルで新しいアクティビティを開くリスト項目をクリックできるため、機能しません。また、誰かがリスト項目をクリックしてから戻るボタンをクリックすると、リストは同じ場所にあるはずなので、onStop() を閉じる (そして onStart() で開く) ことも答えではありません。また、すべてのアクティビティでパブリック静的カーソルも試しましたが、これにも問題がありました。私が試みなかったもう 1 つのことは、カーソル情報を一度にメモリにロードしてすぐに閉じることでしたが、これは理想的とは言えません。
CursorLoader のアイデアはとても気に入っていますが、URI のみを受け入れ、コンテンツ プロバイダーが必要で、rawQuery() を受け入れない点が異なります。私のデータベースには何千ものアイテムがあり、データベース アダプターには 100 種類の異なるクエリ呼び出しがあり、それらすべてを変更するのは非常に面倒です。CursorLoader が最善の方法だと思いますが、Android の実装方法にはがっかりしています。
また、AsyncTaskLoader を使用する誰かが書いた ContentProvider を使用しない CursorLoader の使用法も見たので、ContentProvider は必要ありません。これは今のところ私の最善の策かもしれませんが、データの変更を更新するメカニズムがないことを誰かが指摘しました。私はそれを調べて見る必要があります。