ПрогресDialog застарілий. Який альтернативний варіант використовувати?


215

Я натрапив на те, що ProgressDialogзараз застарілий. Що було б альтернативним використовувати замість цього, крім того ProgressBar. Я використовую андроїд-студію версії 2.3.3.

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

Можливий дублікат ProgressDialog застарілий
Lalit Jadav

Відповіді:


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


оновіть код xml на "@android: color / white"
musterjunk

Щоб отримати горизонтальну смугу,
taranjeetsapra

44

ви можете використовувати 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" у всьому світі
Kishan Donga

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

1
Все добре, але при натисканні на будь-яке місце в діалоговому вікні екрану звільнення. Сервісні дзвінки проходять і користувач може відмовитись від нього та пограти з користувальницьким інтерфейсом, що не є правильним. Будь-яке рішення?
Вівек Кумар

Ви можете встановити його не скасовувати, але обертаючи пристрій або використовувати розділений екран, він все одно буде відхилений, і користувач може взаємодіяти з інтерфейсом, який не готовий. Можливо, AlertDialogтут не слід використовувати.
Meow Cat 2012,

30

Цей клас застарілий на рівні API 26. ProgressDialog - це модальний діалог, який не дозволяє користувачеві взаємодіяти з додатком. Замість використання цього класу слід використовувати індикатор прогресу, як ProgressBar, який можна вбудувати в інтерфейс програми. Крім того, ви можете використовувати сповіщення, щоб повідомити користувача про хід виконання завдання. посилання

Це застаріло Android Oчерез Googleновий стандарт інтерфейсу користувача


1
"Цей клас застарілий на рівні 26 API" використовується замість дати. Вони не хочуть, щоб ви більше його використовували. Так, це через нові стандарти інтерфейсу, але вони застосовуються для кожного рівня API ...
creativecreatorormaybenot

28
"Це застаріло в Android O через новий стандарт інтерфейсу Google" - посилання, будь ласка, новий стандарт інтерфейсу користувача
Ajay S

22
А причина його знецінення полягає в тому, що вона блокує введення користувача? Іноді мені цікаво, який порошок інженери Google хроплять. Набагато простіше використовувати діалогове вікно блокування, ніж приховувати / відключати елементи керування введенням, а потім включати панель прогресу. Дурне мислення з боку Google.
TheRealChx101

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

3
Я думаю, що вони більше зацікавлені у запобіганні зловживань модальними діалогами: іноді їх показують, щоб змусити користувача чекати закінчення операції в умовах, коли користувачеві зовсім не потрібно чекати, але вони можуть продовжувати робити інші дії , тому змушування їх чекати зайве погіршує користувацький досвід. Незважаючи на це, існує багато обставин, за яких користувач не може вибрати, але чекати завершення операції, тому я погоджуюся, що для цих випадків повинен бути непридатний стандартний метод, а не примушувати кожного розробника впроваджувати свій власний.
Fran Marzoa

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

Тоді просто зателефонуйте методу щоразу, коли ви хочете показати прогрес-діалог і передайте істину як аргумент, щоб показати його або помилково, щоб відхилити діалогове вікно.


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 (новий Runnable () {@Override public void run () {dialog.show/dismiss ();}});", якщо виклична нитка не є основною потоком інтерфейсу користувача. (корисно, коли ми використовуємо для виклику з WebView - методу mustoverride.)
SHS

15

Так, програма ProgressDialog застаріла, але діалог - ні.

Ви можете завищити свій власний 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 або створити його самостійно.

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

Вам не потрібно імпортувати будь-яку власну бібліотеку.

Я вважаю за краще використовувати сучасний, AlertDialogтак що це версія Котліна для чудової відповіді, яку опублікував Кішан Донга на цій сторінці.

Котлін Код:

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 У моєму проекті він працює "нормально" в 28 квітнях і так само, як і в нижній апісі. Як свідчить депресія, вона більше не підтримується і може не працювати в майбутньому.
DMonkey

3

ProgressDialog була застаріла в рівні 26 API.

"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;
            }
    );
}

Реалізація Котліна:

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.