Найкращий спосіб показати показник завантаження / прогрес?


146

Який найкращий спосіб відобразити спінер завантаження, поки програма чекає відповіді від сервера?

Чи можна це зробити програмно? Так що мені не потрібно додавати спінер завантаження у файл XML?

Відповіді:


293

ПрогресDialog застарілий від 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

ПрогресDialog застарів після 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

Не впевнений, але чи завжди прогресBar працює у фоновому режимі (просто прихований від інтерфейсу) після того, як робить його невидимим?
Шамху

16

Використовуйте ProgressDialog

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

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

Однак це сьогодні розглядається як анти-модель ( http://www.youtube.com/watch?v=pEGWcMTxs3I)


12
@artworkad シ Отже, який аспект цього вважається поганим - чи прийнята відповідь є прикладом тієї ж антидіаграми? І що рекомендується робити замість цього? Посилання на відеоролик про інші сайти про декілька проблем з UX насправді не покращує цю відповідь.
LarsH


9

Насправді, якщо ви чекаєте відповіді від сервера, це слід робити програмно. Ви можете створити діалог прогресу та відхилити його, але знову ж таки це не "андроїдний шлях".

Наразі рекомендованим методом є використання діалогового фрагмента :

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()

Пам’ятайте, що діалог progress - це спінер або панель прогресу залежно від атрибутів, читайте докладніше у посібнику з api


ProgressDialog.show (контекст контексту, заголовок CharSequence, повідомлення CharSequence); Передаючи параметр заголовка як порожній рядок, видаляється заголовок: ProgressDialog.show (контекст, "", "Завантаження ..");
Раджендра

1
Хороший приклад, хоча мені все ж вдалося скористатися кнопкою "назад". Я думаю, це через вашу змінну dlgAlert (а звідки це походження від btw? :)). У будь-якому випадку - оскільки ви розширюєте діалоговий фрагмент, ви можете просто зателефонувати на 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.