web-dev-qa-db-ja.com

CursorLoaderからカーソルを更新するにはどうすればよいですか?

したがって、MainDisplayActivityと_LoaderManager.LoaderCallbacks<Cursor>_の両方を実装するActivityがあります。ここにあるのは、ListViewです。ContentProviderを使用してデータベースから取得したアジェンダ情報を入力します。カレンダーであるGridViewもあります。セルをクリックすると、アジェンダがクリックされた日に更新されるように設定されています。私の問題は、setOnItemClickListener()内のonCreate()で作成したローダーを再利用すると、作成中の新しいカーソルで情報が更新されないことです。別のIDで新しいローダーを作成するだけで機能しますが、別の日をクリックすると、更新が停止します。問題はカーソルにあります。ローダーからカーソルを更新して、新しいローダーを作成し続ける必要がないようにするにはどうすればよいですか?前もって感謝します!

My MainDisplayActivityクラスのonCreate()でローダーを作成する最初の呼び出し:

_makeProviderBundle(new String[] {"_id, event_name, start_date, start_time, end_date, end_time, location"},
            "date(?) >= start_date and date(?) <= end_date", new String[]{getChosenDate(), getChosenDate()}, null);
    getLoaderManager().initLoader(0, myBundle, MainDisplayActivity.this);

    list.setAdapter(agendaAdapter);
_

これらは_LoaderCallbacks<Cursor>_からオーバーライドされたメソッドです

_@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    Uri baseUri = SmartCalProvider.CONTENT_URI;
    return new CursorLoader(this, baseUri, args.getStringArray("projection"), 
            args.getString("selection"), args.getStringArray("selectionArgs"), args.getBoolean("sortOrder") ? args.getString("sortOrder") : null );
}



@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
    agendaAdapter.swapCursor(arg1);
}



@Override
public void onLoaderReset(Loader<Cursor> arg0) {
    //Not really sure how this works. Maybe I need to fix this here?
    agendaAdapter.swapCursor(null);

}

public void makeProviderBundle(String[] projection, String selection, String[] selectionArgs, String sortOrder){
    /*this is a convenience method to pass it arguments 
     * to pass into myBundle which in turn is passed 
     * into the Cursor loader to query the smartcal.db*/
    myBundle = new Bundle();
    myBundle.putStringArray("projection", projection);
    myBundle.putString("selection", selection);
    myBundle.putStringArray("selectionArgs", selectionArgs);
    if(sortOrder != null) myBundle.putString("sortOrder", sortOrder);
}
_

追加のコードが必要な場合は、遠慮なく質問してください。助けてくれてありがとう!

26
Andy

コードを少し動かしてrestartLoaderを呼び出すだけです。あれは、

  1. ユーザーがリストアイテムをクリックすると、getChosenDate()に返されるプライベートインスタンス変数が何らかの形で変更されます(getChosenDate()が返すものを正確に指定しなかったため、ここでは意図的にあいまいにしています)。 。

  2. 変更が完了したら、LoadergetLoaderManager().restartLoader()を呼び出します。古いデータは破棄され、restartLoaderによってonCreateLoaderが再度呼び出されます。今回は、getChosenDate()は(クリックされたリストアイテムに応じて)異なる値を返します。 onCreateLoaderの実装は次のようになります。

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        Uri baseUri = SmartCalProvider.CONTENT_URI;
    
        makeProviderBundle(
            new String[] { "_id, event_name, start_date, start_time, end_date, end_time, location" },
            "date(?) >= start_date and date(?) <= end_date", 
            new String[]{ getChosenDate(), getChosenDate() }, 
            null);
    
        return new CursorLoader(
                this, 
                baseUri, 
                args.getStringArray("projection"), 
                args.getString("selection"), 
                args.getStringArray("selectionArgs"),    
                args.getBoolean("sortOrder") ? args.getString("sortOrder") : null);
    }
    

それが理にかなっているかどうか教えてください。 :)

41
Alex Lockwood