【发布时间】:2012-08-03 09:41:00
【问题描述】:
美好的一天,正如标题所说,任何人都知道如何在从片段中的 CursorLoader 加载数据时实现进度对话框。在这方面找不到任何例子。任何有关如何操作的链接或指南都将受到高度赞赏。谢谢
【问题讨论】:
标签: android android-fragments android-dialog android-cursorloader
美好的一天,正如标题所说,任何人都知道如何在从片段中的 CursorLoader 加载数据时实现进度对话框。在这方面找不到任何例子。任何有关如何操作的链接或指南都将受到高度赞赏。谢谢
【问题讨论】:
标签: android android-fragments android-dialog android-cursorloader
我认为@Michal 的解决方案非常适合通过ProgressDialog#setIndeterminate(true) 显示不确定的 ProgressDialog,因此我添加了 +1。我不确定向这样的片段添加片段(SomeFragment 添加 DialogFragment ..)是否被批准,因为在提出类似建议之前我已经对 SO 进行了裁剪。另外,在这里使用 ProgressDialog 是可以的,因为它最终是片段的一个组件,因此属于片段之下,而无需作为单独的片段实体存在。
为了扩展这个答案,如果您想提供实时进度更新,那么我建议您在每个“工作单元”(您可以在 CursorLoader 级别计算的最低工作分母)之后应该通过您的Fragment 将监听的LocalBroadcastManger 触发一个事件(保持在本地,没有其他人需要知道)。
在 Fragment 的嵌套 BroadcastReceiver#onReceive() 方法下接收到事件时,可以获得对 Fragment 的 ProgressDialog 的引用,并使用 incrementProgressBy(diff) 或类似方法增加显示的进度。
但是,如果您只想弹出“我正在做某事”对话框,那么将 ProgressDialog 设置为使用 setIndeterminate(true) 就足够了。
最后,您是否考虑过使用将不确定进度对话框添加到 ActionBar 的模式?这就是许多核心应用程序在底层CursorLoader 工作时的运行方式。保持一致会很好。查看与requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS) 相关的项目。
干杯。
更新
要实现最后一种方法,您需要使用类似于(我只是凭记忆写的!)的代码设置您的父活动(拥有 ActionBar 的位);
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);
此时您已经说过,“我希望在我的 Activity ActionBar 中显示旋转进度”。现在,根据您的活动实施,您可以选择通过写入立即在onCreate 中显示不确定的进度条;
setProgressBarIndeterminateVisibility(true);
但是如果一个额外的动作导致 CursorLoader 被启动,这可能太简单了。在整个练习中需要注意的重要一点是,ActionBar 中的进度对话框是拥有 Activity 的功能,不是您的底层 Fragment。您不希望您的片段假设已请求 INDETERMINATE_PROGRESS 功能,因为(a)它可能没有,并且(b)理解这些事情不是特权。换句话说,如果你发现自己在写getActivity().setProgressBarIndeterminateVisibility(true),请停下来想想。
我认为您应该利用一种更加解耦的方法,其中底层 Fragments 表示“我已经开始执行加载”,因此在您的 CursorLoader 回调中,onCreateLoader 类似;
@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());
}
您的 Activity 可以侦听此事件,然后当它接收到该事件时,将不确定的进度条可见性设置为 true。
类似地,当CursorLoader 回调,onLoaderFinished 被调用然后触发另一个事件,如;
@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);
}
最后,您的活动可以将不确定的进度条可见性设置为 false onReceivieing 此事件并将光标结果显示给用户...
【讨论】:
show() 是可以的。原因 getFragmentManager 返回 Activitys fragmentManager, so show()` 方法开始新的 FragmentTransaction 添加 DialogFragment 并提交事务。顺便说一句,我喜欢您显示进度的解决方案。
我认为您可以在 Fragment 中实现 LoaderCallback,您可以使用
回调方法如onCreateLoader 显示对话框,onLoadFinished 关闭对话框。看下面的代码:
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();
}
};
}
【讨论】:
ve got one more idea in mind - to use a Handler`来更新GUI。查看更新示例的帖子。