Program ProgressDialog jest przestarzały. Jakiego alternatywnego użyć?

215

Przekonałem się, że ProgressDialogjest to już nieaktualne. Co byłoby alternatywne zamiast tego ProgressBar. Używam Androida Studio w wersji 2.3.3.

ProgressDialog progressDialog=new ProgressDialog(this);
progressDialog.show();
Sunil P.
źródło
Możliwy duplikat programu ProgressDialog jest przestarzały
Lalit Jadav

Odpowiedzi:

196

Tak, API level 26jest przestarzałe. Zamiast tego możesz użyć progressBar.

Aby utworzyć programowo:

Najpierw zapoznaj się z układem głównym

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

lub

RelativeLayout layout = findViewById(this);

Następnie dodaj pasek postępu

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

Aby wyświetlić pasek postępu

progressBar.setVisibility(View.VISIBLE);

Aby ukryć pasek postępu

progressBar.setVisibility(View.GONE);

Aby wyłączyć interakcję użytkownika, wystarczy dodać następujący kod

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

Aby odzyskać interakcję użytkownika, wystarczy dodać następujący kod

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

Tylko dla odniesienia w przyszłości, należy zmienić android.R.attr.progressBarStyleSmallsię android.R.attr.progressBarStyleHorizontal.

Poniższy kod działa tylko powyżej API level 21

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

Aby go utworzyć za pomocą 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"/>

W twojej działalności

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

Wyświetlanie / ukrywanie paska postępu jest takie samo

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

Oto przykładowy obraz tego, jak by to wyglądało:

Aby uzyskać więcej informacji:
1. Referencja pierwsza
2. Referencja druga

Gowthaman M.
źródło
To tak, jakbyś tego używał i idziesz tak, że tak, w końcu okno postępu jest przestarzałe, więc mogę pokazać światu swój potencjał: D, tylko żartuję, dziękuję bardzo za tę szczegółową odpowiedź.
Mohamed Hajr
1
ale jak ustawić na to setMessage ()?
reverie_ss
Spójrz na to ; stackoverflow.com/questions/18410984/…
Gowthaman M
zaktualizuj kod xml do „@android: color / white”
musterjunk
Aby uzyskać poziomy pasek, użyj: ProgressBar progressBar = new ProgressBar (youractivity.this, null, android.R.attr.progressBarStyleHorizontal); progressBar.setIndeterminate (true);
taranjeetsapra
44

możesz użyć AlertDialogjako ProgressDialogpatrz poniżej kod dla ProgressDialog. Tę funkcję musisz wywołać za każdym razem, gdy wyświetli się okno dialogowe postępu.

Kod:

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

Wynik:

wprowadź opis zdjęcia tutaj

Kishan Donga
źródło
Jak to odrzucić?
Jay Dangar,
1
utwórz jedną klasę podstawową, taką jak BaseActivity, a następnie po dodaniu tego fragmentu kodu, dodaj także jedno okno dialogowe odrzucania metody, ale w tym celu musisz globalnie zdefiniować obiekt okna dialogowego AlertDialog
Kishan Donga
następnie po prostu wywołaj metodę dialog.dismiss () w metodzie ukrywania okna dialogowego.
Kishan Donga,
1
Wszystko jest w porządku, ale stuknięcie w dowolnym miejscu okna dialogowego na ekranie zostaje odrzucone. Połączenia w toku są w toku, a suer jest w stanie je zamknąć i grać z interfejsem użytkownika, co nie jest dobre. Jakieś rozwiązanie?
Vivek Kumar
Możesz ustawić, aby nie można było go anulować, ale obrócenie urządzenia lub użycie podzielonego ekranu zostanie i tak odrzucone, a użytkownik będzie mógł korzystać z interfejsu użytkownika, który nie jest gotowy. Może AlertDialognie powinno się go tutaj używać.
Meow Cat 2012
30

Ta klasa została wycofana z poziomu 26 interfejsu API. ProgressDialog to modalne okno dialogowe, które uniemożliwia użytkownikowi interakcję z aplikacją. Zamiast korzystać z tej klasy, należy użyć wskaźnika postępu, takiego jak ProgressBar, który można osadzić w interfejsie aplikacji. Alternatywnie możesz użyć powiadomienia, aby poinformować użytkownika o postępie zadania. połączyć

Jest przestarzałe ze Android Owzględu na Googlenowy standard interfejsu użytkownika

Oussema Aroua
źródło
1
„Ta klasa została uznana za przestarzałą na poziomie API 26” zamiast daty. Nie chcą, żebyś już z niego korzystał. Tak, wynika to z nowych standardów interfejsu użytkownika, ale dotyczą one każdego poziomu interfejsu API ...
creativecreatorormaybenot
28
„Jest przestarzałe w Androidzie O z powodu nowego standardu interfejsu użytkownika Google” - link proszę nowy standard interfejsu użytkownika
Ajay S
22
A powodem tego jest fakt, że blokuje on wprowadzanie danych przez użytkownika? Czasami zastanawiam się, jaki proszek prychają inżynierowie Google. O wiele łatwiej jest korzystać z okna dialogowego blokowania niż ukrywanie / wyłączanie kontroli wprowadzania, a następnie włączanie paska postępu. Głupie myślenie ze strony Google.
TheRealChx101,
@ TheRealChx101 Interfejs Androida jest zaprojektowany tak, aby użytkownik poczuł fałszywe poczucie wolności kosztem drogich obejść, aby zapobiec krytycznym błędom z tego wynikającym. Poczekaj, aż uzyskasz uprawnienia i to, co operatorzy zapłacili Google, aby powiedzieć, że możesz i nie możesz uzyskać dostępu.
Opuszczony
3
Wydaje mi się, że są bardziej zainteresowani zapobieganiem nadużyciom modalnych okien dialogowych: czasami pokazuje się, że zmuszają użytkownika do zakończenia operacji w okolicznościach, w których użytkownik nie powinien w ogóle musiał czekać, ale może nadal robić inne rzeczy , więc zmuszanie ich do niepotrzebnego pogorszenia komfortu użytkowania. Niezależnie od tego, istnieje wiele okoliczności, w których użytkownik nie ma wyboru, musi tylko poczekać na zakończenie operacji, więc zgadzam się, że powinna istnieć nieaktualna standardowa metoda dla tych przypadków zamiast zmuszania każdego programisty do wdrożenia własnego.
Fran Marzoa,
26

Możesz po prostu zaprojektować interfejs XML dla paska postępu i przekazać go jako widok do AlertDialog, a następnie wyświetlić lub zamknąć okno dialogowe w dowolnym momencie.

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>

Kod kodu wyświetlający okno dialogowe postępu. Po prostu skopiuj ten kod i wklej go we fragmencie.

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

Następnie po prostu wywołaj metodę za każdym razem, gdy chcesz pokazać progressdialog i przekazać true jako argument, aby go pokazać, lub false, aby zamknąć okno dialogowe.

DevMike01
źródło
2
@Alok Rajasukumaran wygląda na to, że używasz aktywności, wystarczy ją zastąpić this, aby wyglądała następująco. AlertDialog.Builder builder = new AlertDialog.Builder(this);Upewnij się, że kopiujesz odpowiedni kod.
DevMike01,
1
layout_toEndOfmożna usunąć, ponieważ nie dlaLinearLayout
Mark
21

Pasek postępu jest bardzo prosty i łatwy w użyciu, zamierzam zrobić to samo, co proste okno dialogowe postępu. Pierwszym krokiem jest to, że możesz utworzyć układ xml okna dialogowego, które chcesz pokazać, powiedzmy, że nazywamy ten układ

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>

następnym krokiem jest utworzenie AlertDialog, który pokaże ten układ za pomocą 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();

teraz pozostaje tylko pokazać i ukryć to okno dialogowe w naszych zdarzeniach związanych z kliknięciem

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

i to wszystko, powinno działać, jak widać, jest to bardzo proste i łatwe do wdrożenia ProgressBar zamiast ProgressDialog. teraz możesz pokazać / odrzucić to okno dialogowe w module obsługi lub ASyncTask, zależnie od potrzeb

Syed Naeem
źródło
Proszę zmienić progress_dialog.show();na builder.show();. Dziękuję Ci.
Matheus Miranda
2
Zmieniłem nazwę na właściwy obiekt AlertDialog na, show()/ dismiss(), ale nie włączyłem, builder.show()ponieważ wtedy, aby go odrzucić, musielibyśmy zrobić, dialog.dismiss()co jest trochę mylące dla kogoś, kto lubi zachować swój kod prosty i łatwy do zrozumienia, a także ponieważ builder.show()zwraca AlertDialogobiekt, a my będziemy musieli zapisać to odwołanie tak jak AlertDialog dialog = builder.show();wtedy dialog.dismiss(), łatwiej jest builder.create()zwrócić w jakimś AlertDialogobiekcie, a następnie użyć tego obiektu, aby wyświetlić i ukryć okno dialogowe
Syed Naeem,
Możemy użyć „runOnUiThread (new Runnable () {@Override public void run () {dialog.show/dismiss ();}});”, jeśli wątek wywołujący nie jest głównym wątkiem interfejsu użytkownika. (przydatne, gdy używamy do wywoływania z WebView - należy zastąpić metody).
SHS
15

Tak, ProgressDialog jest przestarzały, ale Dialog nie.

Możesz nadmuchać własny plik XML (zawierający pasek postępu i ładujący tekst) do obiektu okna dialogowego, a następnie wyświetlić lub ukryć go za pomocą funkcji show()i dismiss(). Oto przykład (Kotlin):

Klasa 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>

W twoim kodzie : po prostu zróbvar dialog = ProgressDialog.progressDialog(context)

Pokazywać: dialog.show()

Ukryć: dialog.dismiss()

Han
źródło
11

Cóż, jeśli naprawdę chcesz postępować wbrew ich woli, nadal możesz użyć Sweet Alert Dialog lub stworzyć go samodzielnie.

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>

Kod 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();
        }
Ramesh Jaya
źródło
2
Miałem straszne doświadczenia ze SweetAlertDialog w środowisku produkcyjnym, bądź bardzo ostrożny, ponieważ przecieka z okna do okna.
Jeremy
dla mnie HideProgressnic nie robi.
Saeed Neamati,
1
Dlaczego warto korzystać z biblioteki, aby wyświetlić okno dialogowe postępu?
Khemraj
6

Nie musisz importować żadnej niestandardowej biblioteki.

Wolę korzystać z nowoczesnego, AlertDialogwięc jest to wersja Kotlin dla świetnej odpowiedzi opublikowanej przez Kishana Dongę na tej stronie.

Kod 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
}

Stosowanie:

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

Wynik:

wprowadź opis zdjęcia tutaj

Alessandro Ornano
źródło
jak korzystać z fragmentu? co to jest fragment w kontekście?
roghayeh hosseini
Zwykle we fragmencie można uzyskać bieżący widok, więc kontekst powinien wyglądać następująco:view!!.context
Alessandro Ornano,
4

Jak wspomniano na stronie dokumentacji, alternatywą jest ProgressBar . ProgressDialogWygląd można replikować, umieszczając plik ProgressBarw AlertDialog.

Nadal możesz go używać, ale Android nie chce, abyś go używał, dlatego jest przestarzały. Dlatego powinieneś rozważyć rozwiązanie swojego problemu w inny sposób, na przykład osadzenie a ProgressBarw swoim Layout.

creativecreatorormaybenot
źródło
@PeterHaddad Działa „normalnie” w API 28 w moim projekcie i tak samo jak w API dolnej. Jak sugeruje to wycofanie, nie jest już obsługiwane i może nie działać w przyszłości.
DMonkey,
3

ProgressDialog został uznany za przestarzały na poziomie API 26.

"Deprecated" odnosi się do funkcji lub elementów, które są w trakcie zastępowania nowszymi.

ProgressDialog to modalne okno dialogowe, które uniemożliwia użytkownikowi interakcję z aplikacją. Zamiast korzystać z tej klasy, należy użyć wskaźnika postępu, takiego jak ProgressBar, który można osadzić w interfejsie aplikacji.

Korzyść

Osobiście powiedziałbym, że ProgressBarma przewagę nad tymi dwoma. ProgressBarto element interfejsu użytkownika, który wskazuje postęp operacji. Wyświetlaj paski postępu użytkownikowi bez przerywania pracy . Pokaż pasek postępu w interfejsie aplikacji.

IntelliJ Amiya
źródło
2

Używam DelayedProgressDialog z https://github.com/Q115/DelayedProgressDialog Robi to samo co ProgressDialog z dodatkową korzyścią opóźnienia, jeśli to konieczne.

Korzystanie z niego jest podobne do ProgressDialog przed Androidem O:

DelayedProgressDialog progressDialog = new DelayedProgressDialog();
progressDialog.show(getSupportFragmentManager(), "tag");
NinjaCowgirl
źródło
2

Możesz skorzystać z tej klasy, którą napisałem. Oferuje tylko podstawowe funkcje. Jeśli potrzebujesz w pełni funkcjonalnego programu ProgressDialog, skorzystaj z tej lekkiej biblioteki .

Konfiguracja stopniowa

Dodaj następującą zależność do module / build.gradle:

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

Jak tego użyć?

Użycie jest podobne do oryginalnego ProgressDialog

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

NB : Musisz zastąpić aktywnośćonBackPressed()

Implementacja Java8:

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

Realizacja Kotlin:

override fun onBackPressed() {
   progressDialog.onBackPressed { super.onBackPressed() }
}
Livin Mathew
źródło
1

Może ten przewodnik może ci pomóc.

Zwykle wolę tworzyć niestandardowe AlertDialogs ze wskaźnikami. Rozwiązuje takie problemy, jak dostosowywanie widoku aplikacji.

Dmitrij Uszkiewicz
źródło
1

Może to pomóc innym ludziom.

Wiele popularnych aplikacji ma różne podejście do pokazywania postępów takich jak żądanie sieciowe, ładowanie plików itp. Ładowanie spinner nie pokazuje, ile treści zostało załadowane lub pozostało do załadowania. Jest okres niepewności, który jest zły w perspektywie UI / UX. Wiele popularnych aplikacji (Facebook, Linkedin itp.) Rozwiązało ten problem, wyświetlając najpierw interfejs użytkownika z odkrytymi kośćmi. Następnie ładowana zawartość jest stopniowo wypełniana na ekranie.

Użyłem migotania do moich aplikacji, aby rozwiązać ten problem.

Jest dobry artykuł na ten temat, który będzie korzystny dla innych ludzi

Rajesh Khadka
źródło
0

W oknie dialogowym postępu użytkownik nie może wykonywać żadnej pracy. Wszystkie procesy w tle są zatrzymywane podczas okna dialogowego postępu. Dlatego wskazane jest, aby pasek postępu użytkownika zamiast okna postępu.

Nevil Ghelani
źródło