问题
Good day, as the title say, anyone know how to implement a progress dialog while loading data from a CursorLoader within a fragment. can't find any example in this regard. Any link or guide on how to do it will be highly appreciated. Thank you
回答1:
I think @Michal's solution would be good for showing an indeterminate ProgressDialog via ProgressDialog#setIndeterminate(true)
so I've added a +1. I'm not sure adding a Fragment to a Fragment like this (SomeFragment adding DialogFragment..) is approved as I've come a cropper on SO before suggesting something similar. Plus, it's ok that the ProgressDialog is used here since ultimately it is a component of the fragment thus belongs under the fragment without needing to exist as a separate Fragment entity.
To expand on this answer, if you were wanting to provide a real-time progress update then I would suggest that after each "unit of work" (the lowest denominator of work you can count at the CursorLoader
level) you should fire an event via the LocalBroadcastManger
(keep it local, no one else needs to know) which your Fragment
will be listening for.
On receiving the event under the Fragment's nested BroadcastReceiver#onReceive()
method can get a reference to your Fragment's ProgressDialog
and increment the displayed progress with incrementProgressBy(diff)
or similar.
If however, you just want to pop-up a "I'm doing something" dialog then setting the ProgressDialog to use setIndeterminate(true)
will suffice.
Finally, have you considered using the pattern of adding the indeterminate progress dialog to the ActionBar? That is how a lot of the core apps operate whilst an underlying CursorLoader
is working. It would be nice to keep it consistent. Check out items pertaining to requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS)
.
Cheers.
Update
To achieve the last approach you need to set-up your parent activity (the bit owning the ActionBar) with code similar to (I'm just writing this from memory!);
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Note that this is requested before you have called setContentView...
getWindow().requestFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.yourLayout);
At this point you have said, "I would like that spinny progress thing in my Activity ActionBar". Now depending on your activity implementation you can choose to show the indeterminate progress bar immediately in onCreate
by writing;
setProgressBarIndeterminateVisibility(true);
But this may be too simplistic if an additional action causes the CursorLoader to be started. What is important to note throughout this exercise is that the progress dialog in the ActionBar is a feature of the owning activity and not your underlying Fragment. You don't want your fragment assuming that the INDETERMINATE_PROGRESS feature has been requested since (a) it may not have and (b) it's not it's prerogative to understand such things. In other words if you find yourself writing getActivity().setProgressBarIndeterminateVisibility(true)
stop and think.
I think you should leverage a more decoupled approach where the underlying Fragments says, "I have started to perform a load" so in your CursorLoader
callback, onCreateLoader
something like;
@Override
public Loader<Result> onCreateLoader(int id, Bundle b) {
// Fire event saying this load is starting.
final Intent loadStarted = new Intent();
loadStarted.setAction(YourFragment.LOAD_STARTED);
return new SomeCursorLoader(this.getActivity());
}
Your activity can be listening for this event and then when it receives it, sets the indeterminate progress bar visibility to true.
Similiarly, when the CursorLoader
callback, onLoaderFinished
is called then fire another event like;
@Override
public void onLoadFinished(Loader<Result> loader, Result data) {
// Fire event saying this load is finished.
final Intent loadFinished = new Intent();
loadFinished.setAction(YourFragment.LOAD_FINISHED);
}
Finally your activity can then sets the indeterminate progress bar visibility to false onReceivie
ing this event and the cursor results are shown to the user...
回答2:
I think you can implement LoaderCallback in your Fragment there you can use
callback methods like onCreateLoader
to show dialog, and onLoadFinished
to dismiss dialog. Look at code below:
public class SomeFragment extends Fragment implements LoaderCallbacks<Result> {
private DialogFragment dialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//you should implement yours DialogFragment
dialog = new DialogFragment();
//Start loader
getLoaderManager().initLoader(0, null, this);
}
@Override
public Loader<Result> onCreateLoader(int id, Bundle b) {
//Show dialog
dialog.show(getFragmentManager(), "TAG");
return new SomeCursorLoader(this.getActivity());
}
@Override
public void onLoadFinished(Loader<Result> loader, Result data) {
handler.sendEmptyMessage(0);
}
@Override
public void onLoaderReset(Loader<Result> arg0) {
}
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
dialog.dismiss();
}
};
}
来源:https://stackoverflow.com/questions/11793166/show-progress-dialog-within-a-cursorloader-in-a-fragment-android