【发布时间】:2014-07-04 07:05:55
【问题描述】:
我很清楚,阻止 UI 通常不是一个好主意,但在某些情况下,我的应用在某些长时间运行的操作(例如从服务器加载数据)完成之前无法执行任何其他工作。
假设用户点击了“加载数据”按钮。为了表明在加载数据之前无法进行 UI 交互,我想将屏幕变灰并显示某种活动指示器。这完全没问题,我只是在屏幕上覆盖了一个新的 Fragment。
问题是:如何呈现这个叠加片段?
public void onLoadDataClick() {
// grey out the screen by simple showing a new Fragment
showActivityIndicatorOverlay();
// Start the long running opeartion
doVeryMuchWork();
dismissActivityIndicatorOverlay();
}
public void showActivityIndicatorOverlay() {
FragmentTransaction ft = context.getSupportFragmentManager().beginTransaction();
ActivityIndicatorOverlayFragment overlayFragment = ActivityIndicatorOverlayFragment.newInstance("Loading Data");
overlayFragment.show(ft, "activityIndicator");
}
这不起作用。叠加层不显示。如果我删除 dismissActivityIndicatorOverlay() 覆盖显示后长时间运行的操作完成。这并不太令人惊讶:我假设显示新片段是在当前运行循环结束或下一个循环开始时处理的。当然,长时间运行的操作必须在运行循环结束之前完成,因此覆盖显示得太晚了......
显而易见的解决方案当然是使用AsyncTask 在后台线程中运行操作:
public void onLoadDataClick() {
LoadDataTask loadTask = new LoadDataTask();
loadTask.execute();
}
private class LoadDataTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
showActivityIndicatorOverlay();
}
@Override
protected Void doInBackground(Void... params) {
doVeryMuchWork();
}
@Override
protected void onPostExecute() {
dismissActivityIndicatorOverlay();
}
}
我很惊讶,这个解决方案也不起作用。它的行为与第一种方法完全一样:没有出现覆盖。当onPostExecute() 被移除时,覆盖会在操作完成后出现。这是为什么呢?
呈现这种活动指标的正确解决方案是什么?
【问题讨论】:
-
我认为最好的方法是使用
ProgressBar来满足您的要求。
标签: java android multithreading android-fragments android-asynctask