So I have my MainDisplayActivity
which implements both Activity
and LoaderManager.LoaderCallbacks<Cursor>
. Here I have A ListView
, which I fill with Agenda information that I get from my database using a ContentProvider. I also have a GridView
which is a calendar. I have it set up when clicking a cell, that the agenda is updated with the day clicked. My problem is that when reusing the Loader I created in onCreate()
inside of the setOnItemClickListener(), it does not refresh the information with the new cursor I am creating. I can just create a new Loader with another ID, and it works once, but once I click another day, it stops refreshing. The problem, lies in the cursor. How can I refresh a cursor from a Loader so I don't have to keep creating a new Loader? Thanks in advance!
所以我有我的MainDisplayActivity,它实现了Activity和LoaderManager.LoaderCallbacks
Initial call to create the Loader in onCreate() in My MainDisplayActivity
class:
初始调用在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);
These are the overridden methods from LoaderCallbacks<Cursor>
这些是来自LoaderCallbacks
@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);
}
Any additional code needed please do not hesitate to ask. Thanks again for any help!
如果需要任何其他代码,请不要犹豫。再次感谢任何帮助!
1 个解决方案
#1
40
You just need to move your code around a little and call restartLoader
. That is,
您只需稍微移动代码并调用restartLoader即可。那是,
-
When the user clicks a list item, you somehow change the private instance variable that is returned in
getChosenDate()
(I am being intentionally vague here because you didn't specify what exactlygetChosenDate()
returns).当用户单击列表项时,您会以某种方式更改在getChosenDate()中返回的私有实例变量(我在这里故意模糊,因为您没有指定getChosenDate()返回的确切内容)。
-
Once the change is made, call
getLoaderManager().restartLoader()
on yourLoader
. Your old data will be discarded andrestartLoader
will triggeronCreateLoader
to be called again. This time around,getChosenDate()
will return a different value (depending on the list item that was clicked) and that should do it. YouronCreateLoader
implementation should look something like this:完成更改后,在Loader上调用getLoaderManager()。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); }
Let me know if that makes sense. :)
如果这有意义,请告诉我。 :)
#1
40
You just need to move your code around a little and call restartLoader
. That is,
您只需稍微移动代码并调用restartLoader即可。那是,
-
When the user clicks a list item, you somehow change the private instance variable that is returned in
getChosenDate()
(I am being intentionally vague here because you didn't specify what exactlygetChosenDate()
returns).当用户单击列表项时,您会以某种方式更改在getChosenDate()中返回的私有实例变量(我在这里故意模糊,因为您没有指定getChosenDate()返回的确切内容)。
-
Once the change is made, call
getLoaderManager().restartLoader()
on yourLoader
. Your old data will be discarded andrestartLoader
will triggeronCreateLoader
to be called again. This time around,getChosenDate()
will return a different value (depending on the list item that was clicked) and that should do it. YouronCreateLoader
implementation should look something like this:完成更改后,在Loader上调用getLoaderManager()。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); }
Let me know if that makes sense. :)
如果这有意义,请告诉我。 :)