如何从CursorLoader刷新光标?

时间:2012-06-18 23:43:05

标签: android debugging android-contentprovider android-loadermanager android-cursorloader

所以我的MainDisplayActivity实现了ActivityLoaderManager.LoaderCallbacks<Cursor>。在这里,我有一个ListView,我填写了我使用ContentProvider从我的数据库获得的议程信息。我还有GridView日历。我点击一个单元格时设置了它,在点击的那一天更新议程。我的问题是,当重用我在setOnItemClickListener()内部的onCreate()中创建的Loader时,它不会使用我正在创建的新游标刷新信息。我可以用另一个ID创建一个新的Loader,它可以运行一次,但是一旦我点击另一天,它就会停止刷新。问题在于光标。如何从Loader刷新游标,这样我就不必继续创建新的Loader?提前谢谢!

初始调用在my MainDisplayActivity类的onCreate()中创建Loader:

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);
}

需要任何其他代码请不要犹豫。再次感谢您的帮助!

1 个答案:

答案 0 :(得分:41)

您只需稍微移动代码并致电restartLoader即可。也就是说,

  1. 当用户点击列表项时,您会以某种方式更改getChosenDate()中返回的私有实例变量(我在这里故意模糊,因为您没有明确指出getChosenDate()返回)。

  2. 完成更改后,请致电getLoaderManager().restartLoader()上的Loader。您的旧数据将被丢弃,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);
    }
    
  3. 如果这有意义,请告诉我。 :)