Показывать индикатор выполнения при загрузке Activity
У меня есть ListActivity
, который запускает другой Activity
на основе выбора списка. Эта вторая Activity
должна загружать справедливый бит данных из Интернета, и поэтому существует заметная задержка между тем, когда пользователь нажимает на элемент и когда отображается Activity
.
Это проблема, потому что в настоящее время у меня нет способа указать пользователю, что их клик обрабатывается (даже если изменить цвет выбранного элемента списка будет достаточно, но я не могу найти хороший способ сделать это). В идеале я мог бы отображать неопределенный ProgressDialog
, пока загружается вторая Activity
.
Я пробовал несколько разных подходов для этого, но ничего не работает по своему желанию.
Я пробовал следующее:
- Извлечение сериализуемых данных (не всех, а часть) в
AsyncTask
в первом Activity
и передачи его как дополнительного для второго. Это не очень хорошо работает, так как ProgressDialog
, созданный мной в onPreExecute()
, не отображался сразу (по какой-то причине он кажется задержан обработкой, выполненной в doInBackground()
.)
Вот код для этого:
AsyncTask<String, Void, String> read = new AsyncTask<String, Void, String>() {
Dialog progress;
@Override
protected void onPreExecute() {
progress = ProgressDialog.show(SearchActivity.this,
"Loading data", "Please wait...");
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
DatasetReader reader = new DatasetReader();
reader.setFundID(params[0]);
reader.addDatsets(FundProfile.datasets);
reader.populate();
return reader.toString();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
progress.dismiss();
}
};
read.execute(selectedItem.getUniqueID());
try {
action = new Intent(SearchActivity.this, FundProfile.class);
action.putExtra("data", read.get());
} catch(Exception ex) {
ex.printStackTrace();
}
Ниже приведен метод onCreate()
для второго подхода:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setTitleColor(Color.WHITE);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setProgressBarVisibility(true);
try {
setContentView(R.layout.fund_profile);
// init some data
setProgressBarVisibility(false);
} catch(Exception ex) {
FundProfile.this.finish();
}
}
Ответы
Ответ 1
Если у вас длительные операции, вы не должны делать их в onCreate в любом случае, так как это заморозит пользовательский интерфейс (независимо от того, отображается ли активность). Пользовательский интерфейс, созданный onCreate, не появится, и пользовательский интерфейс будет не отвечать на запросы до тех пор, пока не закончится вызов onCreate.
Кажется, вы можете запустить свое второе действие и отобразить индикатор выполнения (или requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
), а затем запустить ASyncTask, который будет отвечать за обновление вашего пользовательского интерфейса после получения данных.
Ответ 2
Перемещение создания Intent - и действительно все, что вам нужно сделать после завершения AsyncTask - в onPostExecute:
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
progress.dismiss();
Intent action = new Intent(SearchActivity.this, FundProfile.class);
action.putExtra("data", result);
// ... do more here
}
Проблема заключается в том, что AsyncTask.get() блокирует до завершения задачи. Таким образом, в вышеприведенном коде поток пользовательского интерфейса блокируется, и ProgressDialog никогда не предоставляется возможность появляться до завершения задачи.
Ответ 3
Адам,
Похоже, вы ищете индикатор неопределенного хода: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar2.html
Вы можете отобразить это при загрузке второго Activity
, а затем установить видимость на значение false, как только вторая Activity
загрузила свои данные.