ProgressDialog устарел. Какой альтернативный использовать?


215

Я сталкивался, чтобы видеть, что ProgressDialogтеперь осуждается. Что бы использовать вместо этого, кроме ProgressBar. Я использую Android Studio версии 2.3.3.

ProgressDialog progressDialog=new ProgressDialog(this);
progressDialog.show();

Возможный дубликат ProgressDialog устарел
Лалит

Ответы:


196

Да, API level 26это не рекомендуется. Вместо этого вы можете использовать progressBar.

Чтобы создать его программно:

Сначала получите ссылку на корневой макет

RelativeLayout layout = findViewById(R.id.display);  //specify here Root layout Id

или

RelativeLayout layout = findViewById(this);

Затем добавьте индикатор выполнения

progressBar = new ProgressBar(youractivity.this, null, android.R.attr.progressBarStyleLarge);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(100, 100);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
layout.addView(progressBar, params);

Чтобы показать индикатор выполнения

progressBar.setVisibility(View.VISIBLE);

Чтобы скрыть индикатор выполнения

progressBar.setVisibility(View.GONE);

Чтобы отключить взаимодействие с пользователем, вам просто нужно добавить следующий код

getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                           WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

Чтобы вернуть взаимодействие с пользователем, вам просто нужно добавить следующий код

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

Просто для справки в будущем, изменить android.R.attr.progressBarStyleSmallк android.R.attr.progressBarStyleHorizontal.

Код ниже работает только выше API level 21

progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));

Чтобы создать его через XML:

<ProgressBar
        android:id="@+id/progressbar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:indeterminate="true"
        android:max="100"
        android:backgroundTint="@color/white"
        android:layout_below="@+id/framelauout"
        android:indeterminateTint="#1a09d6"
        android:layout_marginTop="-7dp"/>

В вашей деятельности

progressBar = (ProgressBar) findViewById(R.id.progressbar);

Показывать / скрывать индикатор выполнения - то же самое

 progressBar.setVisibility(View.VISIBLE); // To show the ProgressBar 
 progressBar.setVisibility(View.INVISIBLE); // To hide the ProgressBar

Вот пример изображения того, как это будет выглядеть:

Для более подробной информации:
1. Ссылка один
2. Ссылка два


Как будто вы использовали это, и вы идете, как будто да, наконец, диалог прогресса устарел, поэтому я могу показать свой потенциал миру: D, шучу, большое спасибо за этот подробный ответ.
Мохамед Хаджр

1
но как установитьMessage () к нему?
reverie_ss

посмотри на это ; stackoverflow.com/questions/18410984/…
Gowthaman M

обновите XML-код до «@android: цвет / белый»
Musterjunk

Чтобы получить горизонтальную полосу,
taranjeetsapra

45

Вы можете использовать, AlertDialogкак ProgressDialogуказано ниже код для ProgressDialog. Эту функцию нужно вызывать всякий раз, когда вы показываете диалог прогресса.

Код:

    public void setProgressDialog() {

    int llPadding = 30;
    LinearLayout ll = new LinearLayout(this);
    ll.setOrientation(LinearLayout.HORIZONTAL);
    ll.setPadding(llPadding, llPadding, llPadding, llPadding);
    ll.setGravity(Gravity.CENTER);
    LinearLayout.LayoutParams llParam = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT);
    llParam.gravity = Gravity.CENTER;
    ll.setLayoutParams(llParam);

    ProgressBar progressBar = new ProgressBar(this);
    progressBar.setIndeterminate(true);
    progressBar.setPadding(0, 0, llPadding, 0);
    progressBar.setLayoutParams(llParam);

    llParam = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT);
    llParam.gravity = Gravity.CENTER;
    TextView tvText = new TextView(this);
    tvText.setText("Loading ...");
    tvText.setTextColor(Color.parseColor("#000000"));
    tvText.setTextSize(20);
    tvText.setLayoutParams(llParam);

    ll.addView(progressBar);
    ll.addView(tvText);

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setCancelable(true);
    builder.setView(ll);

    AlertDialog dialog = builder.create();
    dialog.show();
    Window window = dialog.getWindow();
    if (window != null) {
        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
        layoutParams.copyFrom(dialog.getWindow().getAttributes());
        layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT;
        layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT;
        dialog.getWindow().setAttributes(layoutParams);
    }
}

Вывод:

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


Как отмахнуться от этого?
Джей Дангар

1
создайте один базовый класс, такой как BaseActivity, затем после добавления этого фрагмента кода также добавьте один диалог отклонения метода, но для этого вам нужно глобально определить объект 'AlertDialog dialog'
Кишан Донга

затем просто вызовите метод dialog.dismiss () внутри вашего метода скрытия диалога.
Кишан Донга

1
Все хорошо, но при нажатии в любом месте на экране диалоговое окно закрывается. Служба вызывает вызовы, и suer может отклонить его и играть с пользовательским интерфейсом, что не очень хорошо. Есть решение?
Вивек Кумар

Вы можете установить его не отменяемым, но вращая устройство или используя разделенный экран, он все равно будет отклонен, и пользователь может взаимодействовать с пользовательским интерфейсом, который не готов. Может AlertDialogбыть, не следует использовать здесь.
Мяу Кошка 2012

30

Этот класс устарел на уровне API 26. ProgressDialog - это модальное диалоговое окно, которое не позволяет пользователю взаимодействовать с приложением. Вместо использования этого класса вы должны использовать индикатор прогресса, такой как ProgressBar, который может быть встроен в пользовательский интерфейс вашего приложения. Кроме того, вы можете использовать уведомление, чтобы проинформировать пользователя о ходе выполнения задачи. ссылка на сайт

Это устарело Android Oиз-за Googleнового стандарта пользовательского интерфейса


1
«Этот класс устарел на уровне API 26» вместо даты. Они не хотят, чтобы вы использовали это больше. Да, это из-за новых стандартов пользовательского интерфейса, но они применяются для каждого уровня API ...
creativecreatorormaybenot

28
"Это устарело в Android O из-за нового стандарта пользовательского интерфейса Google" - ссылка, пожалуйста, новый стандарт пользовательского интерфейса
Ajay S

22
И причина для того, чтобы осудить это, потому что это блокирует ввод пользователя? Иногда мне интересно, какой порошок пахнут инженеры Google. Гораздо проще использовать блокирующий диалог, чем скрывать / отключать элементы управления вводом, а затем включать индикатор выполнения. Глупое мышление со стороны Google.
TheRealChx101

@ TheRealChx101 Пользовательский интерфейс Android разработан таким образом, чтобы пользователь чувствовал ложное чувство свободы за счет дорогостоящих обходных путей для предотвращения фатальных ошибок, которые в результате этого возникают. Подождите, пока вы не получите разрешения и то, что операторы заплатили Google, чтобы сказать, что вы можете и не можете получить доступ.
Заброшенная корзина

3
Я предполагаю, что они больше заинтересованы в предотвращении злоупотребления модальными диалоговыми окнами: иногда они показывают, что заставляют пользователя ждать окончания операции в обстоятельствах, когда пользователю вообще не нужно ждать, но он может продолжать делать другие вещи , так что заставление их ждать излишне ухудшает пользовательский опыт. Несмотря на это, существует множество обстоятельств, при которых у пользователя нет выбора, кроме как дождаться завершения операции, поэтому я согласен с тем, что для этих случаев должен быть стандартный метод, который не должен быть устаревшим, вместо того, чтобы заставлять каждого разработчика реализовывать свои собственные.
Фран Марсоа

26

Вы можете просто спроектировать интерфейс xml для вашего индикатора выполнения и передать его в качестве представления AlertDialog, а затем показать или закрыть диалоговое окно в любое время.

progress.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:padding="13dp"
    android:layout_centerHorizontal="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ProgressBar
        android:id="@+id/loader"
        android:layout_marginEnd="5dp"
        android:layout_width="45dp"
        android:layout_height="45dp" />
    <TextView
        android:layout_width="wrap_content"
        android:text="Loading..."
        android:textAppearance="?android:textAppearanceSmall"
        android:layout_gravity="center_vertical"
        android:id="@+id/loading_msg"
        android:layout_toEndOf="@+id/loader"
        android:layout_height="wrap_content" />

</LinearLayout>

Код, который отображает диалог прогресса. Просто скопируйте этот код и вставьте его в свой фрагмент.

  AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
       private void setDialog(boolean show){
            builder.setView(R.layout.progress);
            Dialog dialog = builder.create();
            if (show)dialog.show();
            else dialog.dismiss();
        }

Затем просто вызывайте метод всякий раз, когда вы хотите показать progressdialog, и передайте true в качестве аргумента, чтобы показать его, или false, чтобы закрыть диалоговое окно.


2
@Alok Rajasukumaran кажется, что вы используете активность, просто замените ее this, чтобы она выглядела так. AlertDialog.Builder builder = new AlertDialog.Builder(this);Пожалуйста, убедитесь, что вы копируете правильный код.
DevMike01

1
layout_toEndOfмогут быть удалены, поскольку не дляLinearLayout
Марк

21

ProgressBar очень прост и удобен в использовании, я собираюсь сделать то же самое, что и простой диалог прогресса. Первым шагом является то, что вы можете сделать XML-макет диалога, который вы хотите показать, скажем, мы назовем этот макет

layout_loading_dialog.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="20dp">
    <ProgressBar
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="4"
        android:gravity="center"
        android:text="Please wait! This may take a moment." />
</LinearLayout>

Следующим шагом является создание AlertDialog, который покажет этот макет с ProgressBar

AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setCancelable(false); // if you want user to wait for some process to finish,
builder.setView(R.layout.layout_loading_dialog);
AlertDialog dialog = builder.create();

Теперь все, что осталось, это показать и скрыть этот диалог в наших событиях кликов, как это

dialog.show(); // to show this dialog
dialog.dismiss(); // to hide this dialog

и это все, это должно работать, как вы можете видеть, это просто и легко реализовать ProgressBar вместо ProgressDialog. Теперь вы можете показать / закрыть это диалоговое окно либо в Handler, либо в ASyncTask, по вашему желанию.


Пожалуйста, измените progress_dialog.show();на builder.show();. Спасибо.
Матеус Миранда

2
Я изменил имя на правильный объект AlertDialog, show()/ dismiss(), но я не поставил его, builder.show()потому что тогда, чтобы отменить его, мы должны были бы сделать это, dialog.dismiss()что вводит в заблуждение тех, кто любит, чтобы их код был простым и легким для понимания, а также потому что builder.show()возвращает AlertDialogобъект, и нам нужно будет сохранить эту ссылку, как AlertDialog dialog = builder.show();тогда, сделать dialog.dismiss()легче builder.create()возвращать в некотором AlertDialogобъекте, а затем использовать этот объект, чтобы показать и скрыть диалог
Syed Naeem

Мы можем использовать «runOnUiThread (new Runnable () {@Override public void run () {dialog.show/dismiss ();}});», если вызывающий поток не является главным потоком пользовательского интерфейса. (полезно, когда мы используем вызов из WebView - методы mustoverride.)
SHS

15

Да, ProgressDialog устарела, а Dialog - нет.

Вы можете надуть свой собственный XML - файл (содержащий индикатор и текст загрузки) в диалоговый объект , а затем отобразить или скрыть его , используя show()и dismiss()функцию. Вот пример (Котлин):

Класс ProgressDialog :

class ProgressDialog {
companion object {
    fun progressDialog(context: Context): Dialog{
        val dialog = Dialog(context)
        val inflate = LayoutInflater.from(context).inflate(R.layout.progress_dialog, null)
        dialog.setContentView(inflate)
        dialog.setCancelable(false)
        dialog.window!!.setBackgroundDrawable(
                ColorDrawable(Color.TRANSPARENT))
        return dialog
    }
  }
}

XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:background="#fff"
android:padding="13dp"
android:layout_height="wrap_content">
<ProgressBar
    android:id="@+id/progressBar"
    style="?android:attr/progressBarStyle"
    android:layout_width="100dp"
    android:layout_margin="7dp"
    android:layout_height="100dp"
    android:layout_above="@+id/no_jobs_pickups"/>
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_margin="7dp"
    android:layout_toEndOf="@+id/progressBar"
    android:text="Loading..." />
</RelativeLayout>

В вашем коде : просто делайvar dialog = ProgressDialog.progressDialog(context)

Показывать: dialog.show()

Прятаться: dialog.dismiss()


11

Ну, если вы действительно хотите пойти против их воли, вы все равно можете использовать Sweet Alert Dialog или создать его самостоятельно.

progress_dialog_layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TableRow
        android:layout_centerInParent="true"
        android:layout_width="match_parent"
        android:layout_height="64dp" >

        <ProgressBar
            android:id="@+id/progressBar2"
            style="?android:attr/progressBarStyle"
            android:layout_width="wrap_content"
            android:layout_height="match_parent" />

        <TextView
            android:gravity="center|left"
            android:id="@+id/textView9"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:textColor="@color/black"
            android:textSize="18sp"
            android:text="Downloading data. Please wait.." />
    </TableRow>
</RelativeLayout>

Java-код:

AlertDialog b;
AlertDialog.Builder dialogBuilder;

public void ShowProgressDialog() {
dialogBuilder = new AlertDialog.Builder(DataDownloadActivity.this);
LayoutInflater inflater = (LayoutInflater) getSystemService( Context.LAYOUT_INFLATER_SERVICE );
            View dialogView = inflater.inflate(R.layout.progress_dialog_layout, null);
            dialogBuilder.setView(dialogView);
            dialogBuilder.setCancelable(false);
            b = dialogBuilder.create();
            b.show();
        }

        public void HideProgressDialog(){

            b.dismiss();
        }

2
У меня был ужасный опыт работы с SweetAlertDialog в производственных условиях, будьте очень осторожны, так как он просачивается из окна в окно.
Джереми

для меня HideProgressничего не делает.
Саид Нимати

1
Зачем использовать библиотеку, чтобы показать диалог прогресса?
Хемрай

6

ProgressBar - лучшая альтернатива для ProgressDialog. Элемент пользовательского интерфейса, который указывает на ход операции.

Для получения дополнительной информации см. Этот документ Google: https://developer.android.com/reference/android/widget/ProgressBar.html


16
Он сказал "кроме прогресса".
creativecreatorormaybenot

6

Вам не нужно импортировать любую пользовательскую библиотеку.

Я предпочитаю использовать модерн, AlertDialogтак что это версия Kotlin для отличного ответа, размещенного Кишан Донгой на этой странице.

Код Котлина:

fun setProgressDialog(context:Context, message:String):AlertDialog {
    val llPadding = 30
    val ll = LinearLayout(context)
    ll.orientation = LinearLayout.HORIZONTAL
    ll.setPadding(llPadding, llPadding, llPadding, llPadding)
    ll.gravity = Gravity.CENTER
    var llParam = LinearLayout.LayoutParams(
                  LinearLayout.LayoutParams.WRAP_CONTENT,
                  LinearLayout.LayoutParams.WRAP_CONTENT)
    llParam.gravity = Gravity.CENTER
    ll.layoutParams = llParam

    val progressBar = ProgressBar(context)
    progressBar.isIndeterminate = true
    progressBar.setPadding(0, 0, llPadding, 0)
    progressBar.layoutParams = llParam

    llParam = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT)
    llParam.gravity = Gravity.CENTER
    val tvText = TextView(context)
    tvText.text = message
    tvText.setTextColor(Color.parseColor("#000000"))
    tvText.textSize = 20.toFloat()
    tvText.layoutParams = llParam

    ll.addView(progressBar)
    ll.addView(tvText)

    val builder = AlertDialog.Builder(context)
    builder.setCancelable(true)
    builder.setView(ll)

    val dialog = builder.create()
    val window = dialog.window
    if (window != null) {
        val layoutParams = WindowManager.LayoutParams()
        layoutParams.copyFrom(dialog.window?.attributes)
        layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT
        layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT
                dialog.window?.attributes = layoutParams
    }
    return dialog
}

Использование:

val dialog = setProgressDialog(this, "Loading..")
dialog.show()

Вывод:

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


как использовать во фрагменте? что такое контекст во фрагменте?
roghayeh hosseini

Обычно в вашем фрагменте вы можете получить текущий вид, поэтому контекст должен быть:view!!.context
Алессандро Орнано

4

Как уже упоминалось на странице документации, альтернатива есть ProgressBar . ProgressDialogВнешний вид может быть воспроизведен путем размещения ProgressBarв AlertDialog.

Вы все еще можете использовать его, но Android не хочет, чтобы вы использовали его, поэтому он устарел. Таким образом, вы должны рассмотреть решение вашей проблемы другим способом, например, встраивание ProgressBarв вашу Layout.


@PeterHaddad Он работает "нормально" в API 28 в моем проекте и так же, как в более низких API. Как следует из устаревшего, он больше не поддерживается и может не работать в будущем.
DMonkey

3

ProgressDialog устарел на уровне API 26.

"Deprecated" относится к функциям или элементам, которые находятся в процессе замены на более новые.

ProgressDialog - это модальное диалоговое окно, которое не позволяет пользователю взаимодействовать с приложением. Вместо использования этого класса вы должны использовать индикатор прогресса, например ProgressBar, который может быть встроен в пользовательский интерфейс вашего приложения.

преимущество

Я бы лично сказал, что ProgressBarимеет преимущество над двумя. ProgressBarявляется элементом пользовательского интерфейса, который указывает на ход операции. Отображать индикаторы выполнения для пользователя без перерыва . Показать индикатор выполнения в пользовательском интерфейсе вашего приложения.


2

Я использую DelayedProgressDialog из https://github.com/Q115/DelayedProgressDialog. Он делает то же самое, что и ProgressDialog, с дополнительным преимуществом задержки при необходимости.

Использование аналогично ProgressDialog до Android O:

DelayedProgressDialog progressDialog = new DelayedProgressDialog();
progressDialog.show(getSupportFragmentManager(), "tag");

2

Вы можете использовать этот класс, который я написал. Он предлагает только основные функции. Если вам нужен полнофункциональный ProgressDialog, используйте эту легковесную библиотеку .

Настройка Gradle

Добавьте следующую зависимость в module / build.gradle:

compile 'com.lmntrx.android.library.livin.missme:missme:0.1.5'

Как это использовать?

Использование аналогично оригинальному ProgressDialog

ProgressDialog progressDialog = new 
progressDialog(YourActivity.this);
progressDialog.setMessage("Please wait");
progressDialog.setCancelable(false);
progressDialog.show();
progressDialog.dismiss();

NB . Вы должны переопределить активностьonBackPressed()

Реализация Java8:

@Override
public void onBackPressed() {
    progressDialog.onBackPressed(
            () -> {
                super.onBackPressed();
                return null;
            }
    );
}

Kotlin Реализация:

override fun onBackPressed() {
   progressDialog.onBackPressed { super.onBackPressed() }
}

1

Может быть, это руководство может помочь вам.

Обычно я предпочитаю делать собственные AlertDialogs с индикаторами. Это решает такие проблемы, как настройка представления приложения.


1

Это может помочь другим людям.

Во многих популярных приложениях используется другой подход, позволяющий показать ход выполнения каких-либо задач, таких как сетевой запрос, загрузка файла и т. Д. При загрузке счетчик не показывает, сколько контента было загружено или осталось загрузить. Существует период неопределенности, что плохо с точки зрения UI / UX. Множество популярных приложений (Facebook, Linkedin и т. Д.) Решили эту проблему, сначала показав голые интерфейсы пользователя. Затем загруженный контент постепенно заполняется на экране.

Я использовал мерцание для своих приложений, чтобы решить эту проблему.

Есть хорошая статья об этом, которая будет полезна для других людей.


0

В диалоговом окне выполнения пользователь не может выполнять какую-либо работу. Все фоновые процессы останавливаются во время диалога прогресса. Таким образом, желательно, чтобы пользователь прогресс-бар, а не диалог прогресса.


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