Лучший способ показать индикатор загрузки / прогресса?


147

Каков наилучший способ показать загрузчик, пока приложение ожидает ответа от сервера?

Это можно сделать программно? Чтобы мне не нужно было добавлять загрузчик в файл XML?

Ответы:


293

ProgressDialog устарела из Android Oreo. Вместо этого используйте ProgressBar

ProgressDialog progress = new ProgressDialog(this);
progress.setTitle("Loading");
progress.setMessage("Wait while loading...");
progress.setCancelable(false); // disable dismiss by tapping outside of the dialog
progress.show();
// To dismiss the dialog
progress.dismiss();

ИЛИ

ProgressDialog.show(this, "Loading", "Wait while loading...");

Узнайте больше здесь.

Кстати, Spinner имеет другое значение в Android. (Это похоже на выпадающий список в HTML)


1
С веб-сайта разработчика Android: STYLE_SPINNER Создает ProgressDialog с круглой, вращающейся индикатором выполнения.
Текиламан

34
Это работает, но когда я проверил это, я мог закрыть диалоговое окно, коснувшись экрана за его пределами или нажав кнопку « Назад» . Я исправил это, добавив вызов progress.setCancelable(false);.
Сэм

1
Спасибо за нижний комментарий. Я сходил с ума, потому что я пытался заставить «прядильщика» работать в течение часа.
Может Пойразоглу

превосходно, теперь я могу использовать диалог прогресса
Faisal


17

ProgressDialog устарел после API уровня 26 https://developer.android.com/reference/android/app/ProgressDialog.html

Я включаю ProgressBar в свой макет

   <ProgressBar
        android:layout_weight="1"
        android:id="@+id/progressBar_cyclic"
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:minHeight="40dp"
        android:minWidth="40dp" />

и измените его видимость на .GONE | .ВИДИМ в зависимости от варианта использования.

    progressBar_cyclic.visibility = View.VISIBLE

Не уверен, но всегда ли progressBar работает в фоновом режиме (просто скрыт от пользовательского интерфейса) после того, как делает его невидимым?
Шамбху

16

использование ProgressDialog

ProgressDialog.show(Context context, CharSequence title, CharSequence message);

введите описание изображения здесь

Однако сегодня это считается анти-паттерном (2013): http://www.youtube.com/watch?v=pEGWcMTxs3I


12
@artworkad シ Так какой аспект этого считается плохим - является ли принятый ответ примером того же антипаттерна? И что вместо этого рекомендуется делать? Ссылка на стороннее видео о множественных проблемах с UX на самом деле не улучшает этот ответ.
LarsH


9

На самом деле, если вы ждете ответа от сервера, это должно быть сделано программно. Вы можете создать диалог прогресса и закрыть его, но опять же, это не «путь для Android».

В настоящее время рекомендуется использовать метод DialogFragment :

public class MySpinnerDialog extends DialogFragment {

    public MySpinnerDialog() {
        // use empty constructors. If something is needed use onCreate's
    }

    @Override
    public Dialog onCreateDialog(final Bundle savedInstanceState) {

        _dialog = new ProgressDialog(getActivity());
        this.setStyle(STYLE_NO_TITLE, getTheme()); // You can use styles or inflate a view
        _dialog.setMessage("Spinning.."); // set your messages if not inflated from XML

        _dialog.setCancelable(false);  

        return _dialog;
    }
}

Затем в своей деятельности вы устанавливаете свой менеджер фрагментов и показывает диалоговое окно после запуска ожидания сервера:

FragmentManager fm = getSupportFragmentManager();
MySpinnerDialog myInstance = new MySpinnerDialog();
}
myInstance.show(fm, "some_tag");

Как только ваш сервер ответит, вы его отклоните:

myInstance.dismiss()

Помните, что progressdialog - это счетчик или индикатор выполнения в зависимости от атрибутов, читайте больше в руководстве по API.


ProgressDialog.show (Контекстный контекст, заголовок CharSequence, сообщение CharSequence); Передача параметра title в виде пустой строки удаляет заголовок: ProgressDialog.show (context, "", "Loading ..");
Раджендра

1
Прекрасный пример, хотя мне все еще удавалось использовать кнопку «Назад». Я думаю, что это из-за вашей переменной dlgAlert (и откуда это происходит между прочим? :)). В любом случае - поскольку вы расширяете диалоговый фрагмент, вы можете просто вызвать setCancelable (false), и он будет работать.
Лассе

Фиксация транзакций фрагмента в неопределенное время, когда сервер возвращает ответ, не кажется надежной. Например, когда ответ возвращается, действие, в котором находится фрагмент, может находиться в неправильном состоянии. Любое решение?
Джонас

Убедитесь , что вы импортируете android.support.v4.app.DialogFragment и не android.app.DialogFragment, или вы не можете использовать getSupportFragmentManager (см stackoverflow.com/questions/27514338/... )
StCleezy


6

Вот как я это сделал, чтобы одновременно можно было открыть только один диалог прогресса. Основано на ответе Сураджа Бахая

private ProgressDialog progress;



public void showLoadingDialog() {

    if (progress == null) {
        progress = new ProgressDialog(this);
        progress.setTitle(getString(R.string.loading_title));
        progress.setMessage(getString(R.string.loading_message));
    }
    progress.show();
}

public void dismissLoadingDialog() {

    if (progress != null && progress.isShowing()) {
        progress.dismiss();
    }
}

Я также должен был использовать

protected void onResume() {
    dismissLoadingDialog();
    super.onResume();
}

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.