ProgressDialog è obsoleto. Qual è quello alternativo da utilizzare?


Risposte:


196

Sì, API level 26è obsoleto. Invece, puoi usare progressBar.

Per crearlo programmaticamente:

Innanzitutto ottenere un riferimento al layout di root

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

o

RelativeLayout layout = findViewById(this);

Quindi aggiungere la barra di avanzamento

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

Per mostrare la barra di avanzamento

progressBar.setVisibility(View.VISIBLE);

Per nascondere la barra di avanzamento

progressBar.setVisibility(View.GONE);

Per disabilitare l'interazione dell'utente è sufficiente aggiungere il seguente codice

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

Per ottenere l'interazione dell'utente è sufficiente aggiungere il seguente codice

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

Solo per riferimento futuro, cambiare l' android.R.attr.progressBarStyleSmalla android.R.attr.progressBarStyleHorizontal.

Il codice seguente funziona solo sopra API level 21

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

Per crearlo tramite 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"/>

Nella tua attività

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

Mostrare / nascondere la barra di avanzamento è lo stesso

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

Ecco un'immagine di esempio di come sarebbe:

Per maggiori dettagli:
1. Riferimento uno
2. Riferimento due


È come se lo stessi usando e vai come sì, finalmente la finestra di dialogo sui progressi è obsoleta, quindi posso mostrare il mio potenziale al mondo: D, sto solo scherzando, grazie mille per la risposta dettagliata.
Mohamed Hajr,

1
ma come impostareMessage () ad esso?
reverie_ss


aggiorna il codice xml a "@android: color / white"
musterjunk

Per ottenere la barra orizzontale, utilizzare: ProgressBar progressBar = new ProgressBar (youractivity.this, null, android.R.attr.progressBarStyleHorizontal); progressBar.setIndeterminate (true);
taranjeetsapra,

45

puoi usare AlertDialogcome ProgressDialogriferimento sotto il codice per il ProgressDialog. Questa funzione è necessario chiamare ogni volta che si visualizza una finestra di dialogo di avanzamento.

Codice:

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

Produzione:

inserisci qui la descrizione dell'immagine


Come respingerlo?
Jay Dangar,

1
crea una classe base come BaseActivity quindi dopo aver aggiunto questo pezzo di codice, aggiungi anche una finestra di dialogo di eliminazione del metodo, ma per questo, devi definire l'oggetto 'AlertDialog dialog' a livello globale
Kishan Donga,

quindi chiama semplicemente il metodo dialog.dismiss () all'interno del tuo metodo di dialogo Nascondi.
Kishan Donga,

1
Va tutto bene, ma toccando un punto qualsiasi della finestra di dialogo viene respinto. Le chiamate di servizio in corso e suer sono in grado di chiuderlo e giocare con l'interfaccia utente che non è buona. Qualunque soluzione?
Vivek Kumar il

Puoi impostarlo non cancellabile, ma ruotando il dispositivo o usando lo schermo diviso verrebbe comunque respinto e l'utente potrebbe interagire con l'interfaccia utente che non è pronta. Forse AlertDialognon dovrebbe essere usato qui.
Meow Cat 2012

30

Questa classe è stata deprecata a livello di API 26. ProgressDialog è una finestra di dialogo modale che impedisce all'utente di interagire con l'app. Invece di utilizzare questa classe, è necessario utilizzare un indicatore di progresso come ProgressBar, che può essere incorporato nell'interfaccia utente dell'app. In alternativa, è possibile utilizzare una notifica per informare l'utente sullo stato di avanzamento dell'attività. collegamento

È obsoleto a Android Ocausa del Googlenuovo standard dell'interfaccia utente


1
"Questa classe è stata deprecata nel livello API 26" viene utilizzata al posto di una data. Non vogliono più che tu lo usi. Sì, è a causa dei nuovi standard dell'interfaccia utente, ma si applicano a tutti i livelli API ...
creativecreatorormaybenot

28
"È deprecato su Android O a causa del nuovo standard dell'interfaccia utente di Google" - link, per favore, nuovo standard dell'interfaccia utente
Ajay S

22
E il motivo per deprecarlo è perché blocca l'input dell'utente? A volte mi chiedo che tipo di polvere gli ingegneri di Google stiano sbuffando. È molto più facile utilizzare una finestra di dialogo di blocco che dover nascondere / disabilitare i controlli di input e quindi abilitare una barra di avanzamento. Pensiero sciocco da parte di Google.
TheRealChx101

@ TheRealChx101 L'interfaccia utente di Android è progettata per far sentire all'utente un falso senso di libertà a scapito di costose soluzioni alternative per evitare errori fatali che ne derivano. Aspetta di ottenere le autorizzazioni e ciò che i corrieri hanno pagato Google per dire che puoi e non puoi accedere.
Carrello abbandonato

3
Immagino che siano più interessati a prevenire l'abuso delle finestre di dialogo modali: a volte vengono mostrati per far attendere all'utente la fine di un'operazione in circostanze in cui l'utente non dovrebbe attendere affatto, ma potrebbe continuare a fare altre cose , quindi farli aspettare inutilmente degrada l'esperienza dell'utente. Ciononostante, ci sono molte circostanze in cui non c'è altra scelta per l'utente che attendere il completamento di un'operazione, quindi sono d'accordo che ci dovrebbe essere un metodo standard non deprecato per questi casi invece di forzare ogni sviluppatore a implementare il proprio.
Fran Marzoa,

26

Puoi semplicemente progettare un'interfaccia xml per la tua barra di avanzamento e passarla come vista a un AlertDialog, quindi mostrare o chiudere la finestra di dialogo ogni volta che vuoi.

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>

Il codice codice che visualizza la finestra di dialogo di avanzamento. Basta copiare questo codice e incollarlo nel tuo frammento.

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

Quindi chiama semplicemente il metodo ogni volta che vuoi mostrare il progressdialog e passa true come argomento per mostrarlo o false per chiudere la finestra di dialogo.


2
@Alok Rajasukumaran sembra che tu stia utilizzando l'attività, semplicemente sostituiscila con this, in modo che appaia così AlertDialog.Builder builder = new AlertDialog.Builder(this);. Assicurati di copiare il codice giusto.
DevMike01

1
layout_toEndOfpuò essere rimosso poiché non perLinearLayout
Mark

21

ProgressBar è molto semplice e facile da usare, intendo farlo come una semplice finestra di dialogo sullo stato di avanzamento. il primo passo è che puoi creare un layout xml della finestra di dialogo che vuoi mostrare, diciamo che chiamiamo questo layout

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>

il prossimo passo è creare AlertDialog che mostrerà questo layout con 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();

ora non resta che mostrare e nascondere questa finestra di dialogo nei nostri eventi di clic in questo modo

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

e questo è tutto, dovrebbe funzionare, come puoi vedere è decisamente semplice e facile implementare ProgressBar invece di ProgressDialog. ora puoi mostrare / eliminare questa finestra di dialogo in Handler o ASyncTask, dipende dalle tue necessità


Per favore, cambia progress_dialog.show();in builder.show();. Grazie.
Matheus Miranda,

2
Ho cambiato il nome nell'oggetto AlertDialog giusto su, show()/ dismiss(), ma non l'ho messo builder.show()perché poi per scartarlo dovremmo fare, il dialog.dismiss()che è un po 'confuso per qualcuno a cui piace mantenere il proprio codice semplice e facile da capire, e anche perché builder.show()restituisce AlertDialogoggetto, e dovremo salvare quel riferimento come AlertDialog dialog = builder.show();allora dialog.dismiss(), è più facile avere un builder.create()ritorno in qualche AlertDialogoggetto, e quindi usare quell'oggetto per mostrare e nascondere il dialogo
Syed Naeem

È possibile utilizzare "runOnUiThread (new Runnable () {@Override public void run () {dialog.show/dismiss ();}});", se il thread chiamante non è il thread dell'interfaccia utente principale. (utile quando usiamo per chiamare da WebView - dovremmo sovrascrivere i metodi.)
SHS

15

Sì, ProgressDialog è obsoleto ma Dialog no.

È possibile gonfiare il proprio file XML (contenente una barra di avanzamento e un testo di caricamento) nell'oggetto della finestra di dialogo e quindi visualizzarlo o nasconderlo utilizzando le funzioni show()e dismiss(). Ecco un esempio (Kotlin):

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

Nel tuo codice : fallovar dialog = ProgressDialog.progressDialog(context)

Mostrare: dialog.show()

Nascondere: dialog.dismiss()


11

Bene, se vuoi davvero andare contro la loro volontà, puoi comunque usare la finestra di dialogo Sweet Alert o crearne uno da solo.

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>

Codice 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
Ho avuto esperienze terribili con SweetAlertDialog in un ambiente di produzione, siate molto cauti mentre fuoriesce da una finestra all'altra.
Jeremy,

per me HideProgressnon fa niente.
Saeed Neamati,

1
Perché usare una libreria solo per mostrare una finestra di avanzamento?
Khemraj,


6

Non è necessario importare alcuna libreria personalizzata.

Preferisco usare il moderno, AlertDialogquindi questa è la versione di Kotlin per l'ottima risposta pubblicata da Kishan Donga in questa pagina.

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

Uso:

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

Produzione:

inserisci qui la descrizione dell'immagine


come usare in frammento? che cos'è il contesto in frammento?
roghayeh hosseini,

Di solito nel tuo frammento puoi ottenere la tua vista attuale, quindi il contesto dovrebbe essere:view!!.context
Alessandro Ornano,

4

Come indicato nella pagina della documentazione, l'alternativa è ProgressBar . ProgressDialogL 'aspetto può essere replicato posizionando a ProgressBarin un AlertDialog.

Puoi ancora usarlo, ma Android non vuole che tu lo usi, ecco perché è deprecato. Quindi dovresti considerare di risolvere il tuo problema in un altro modo, come incorporare un ProgressBarnel tuo Layout.


@PeterHaddad Funziona "normalmente" in api 28 nel mio progetto e lo stesso che nell'apis inferiore. Come suggerisce la deprecazione, non è più supportato e potrebbe non funzionare in futuro.
DMonkey,

3

ProgressDialog è stato deprecato nel livello API 26.

"Deprecated" si riferisce a funzioni o elementi che sono in procinto di essere sostituiti da nuovi.

ProgressDialog è una finestra di dialogo modale che impedisce all'utente di interagire con l'app. Invece di usare questa classe, dovresti usare un indicatore di progresso simile ProgressBar, che può essere incorporato nell'interfaccia utente della tua app.

Vantaggio

Personalmente direi che ProgressBarha il vantaggio rispetto ai due. ProgressBarè un elemento dell'interfaccia utente che indica l'avanzamento di un'operazione. Visualizza le barre di avanzamento per un utente in modo non interruttivo . Mostra la barra di avanzamento nell'interfaccia utente dell'app.


2

Uso DelayedProgressDialog da https://github.com/Q115/DelayedProgressDialog Fa lo stesso di ProgressDialog con l'ulteriore vantaggio di un ritardo, se necessario.

Usarlo è simile a ProgressDialog prima di Android O:

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

2

Puoi usare questa classe che ho scritto. Offre solo le funzioni di base. Se si desidera un ProgressDialog completamente funzionale, utilizzare questa libreria leggera .

Impostazione del grado

Aggiungi la seguente dipendenza a module / build.gradle:

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

Come usarlo?

L'utilizzo è simile al ProgressDialog originale

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

NB : è necessario ignorare le attivitàonBackPressed()

Implementazione Java8:

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

Implementazione di Kotlin:

override fun onBackPressed() {
   progressDialog.onBackPressed { super.onBackPressed() }
}
  • Consulta l' app di esempio per la completa implementazione
  • La documentazione completa è disponibile qui

1

Forse questa guida potrebbe aiutarti.

Di solito preferisco creare dialoghi personalizzati con indicatori. Risolve problemi come la personalizzazione della vista App.


1

Potrebbe aiutare altre persone.

Molte app popolari hanno un approccio diverso per mostrare lo stato di avanzamento di qualsiasi richiesta di rete, caricamento di file, ecc. Il caricamento di spinner non mostra la quantità di contenuto che è stato caricato o che resta da caricare. C'è un periodo di incertezza che è negativo nella prospettiva di UI / UX. Molte app popolari (Facebook, Linkedin, ecc.) Hanno risolto questo problema mostrando prima le schermate dell'interfaccia utente. Quindi il contenuto caricato viene popolato gradualmente sullo schermo.

Ho usato il luccichio per le mie applicazioni per risolvere questo problema.

C'è un buon articolo su questo che sarà utile per altre persone


0

Nella finestra di dialogo di avanzamento, l'utente non può eseguire alcun tipo di lavoro. Tutti i processi in background vengono arrestati durante la finestra di dialogo di avanzamento. Pertanto, si consiglia di utilizzare la barra di avanzamento anziché la finestra di dialogo di avanzamento.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.