Android przycisk Wstecz i okno postępu

Mam AsyncTask , który pokazuje progressDialog podczas pracy (wywołuje runOnUiThread z wewnątrz doInBackground, aby pokazać okno postępu).

Podczas jego działania chcę zezwolić na użycie przycisku back, aby anulować operację; ktoś inny miał ten problem: przycisk BACK nie działa, podczas gdy progressDialog działa

Z jakiego powodu nie mogę odpowiedzieć na ten wątek, dlatego muszę zacząć kolejny?! (Kolejne pytanie na kolejny dzień)

Miałem ten sam pomysł co Sandy, ale ten kod nigdy nie jest wywoływany, podczas gdy progressDialog pokazuje, dlaczego tak jest? Zaimplementowałem go wewnątrz mojej głównej klasy aktywności, czy progressDialog tymczasowo usuwa fokus pierwszoplanowy z mojej klasy?

Author: Community, 2011-03-10

9 answers

Najpierw powinieneś pokazać swoje okno dialogowe z OnPreExecute, ukryć je w OnPostExecute i - jeśli to konieczne-zmodyfikować je, publikując postęp. (Zobacz tutaj )

Teraz do pytania: ProgressDialog.show() może przyjąć OnCancelListener jako argument. Powinieneś podać taki, który wywoła cancel() na wystąpieniu okna postępu.

Przykład:

    @Override
    protected void onPreExecute(){
        _progressDialog = ProgressDialog.show(
                YourActivity.this,
                "Title",
                "Message",
                true,
                true,
                new DialogInterface.OnCancelListener(){
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        YourTask.this.cancel(true);
                        finish();
                    }
                }
        );
    }

Gdzie _progressDialog jest ProgressDialog członkiem YourTask.

Ta klasa była przestarzała w API na poziomie 26. ProgressDialog jest modalny okno dialogowe, które zapobiega użytkownika z interakcji z aplikacją. Zamiast korzystając z tej klasy, powinieneś użyć wskaźnika postępu, takiego jak Pasek postępu, który można osadzać w interfejsie aplikacji. Alternatywnie, możesz użyć powiadomienia, aby poinformować użytkownika o postępie zadania. LINK

 44
Author: user634618,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-09 08:28:15

Cóż, miałem ten sam problem. Najprostszą metodą, która mi się sprawdziła, jest użycie progressDialog.setCancelable(true).. Określa, czy okno dialogowe można anulować, naciskając klawisz back.. Spróbuj i daj mi znać, czy to działa dla Ciebie, czy nie. Powodzenia

 13
Author: Farhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-20 07:14:09

Można to osiągnąć za pomocą następującego fragmentu kodu:

progress.setCancelable(true);
progress.setCanceledOnTouchOutside(false);

Progress jest obiektem ProgressDialog...

Spowoduje to zamknięcie okna dialogowego przyciskiem wstecz, ale uniemożliwi wejście dotykowe...

 13
Author: Jahid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-03 04:30:28

Właśnie znalazłem idealne i najprostsze rozwiązanie tego problemu. Istnieje metoda w ProgressDialog, aby ustawić KeyListener.

progressDialog.setOnKeyListener(new OnKeyListener() {
    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        if(keyCode==KeyEvent.KEYCODE_BACK && !event.isCanceled()) {
            if(progressDialog.isShowing()) {
                //your logic here for back button pressed event
            } 
            return true;
        }
        return false;
    }
});
To działa dobrze z setCancelable(false). Sprawdzam też event.isCanceled(), bo bez tego miałem dwa zdarzenia. Przetestowałem to na urządzeniu Lollipop z kluczami sprzętowymi i bez nich.
 8
Author: Ashish Tanna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-31 03:55:57

Traktowanie przycisku wstecz jak anulowania nie jest prawidłowym sposobem.
Anulowanie występuje również, gdy użytkownik dotknie ekranu poza oknem dialogowym. Chcesz rozróżnić te dwa działania, prawda?

Poprawnym podejściem byłoby rozszerzenie klasy ProgressDialog i nadpisanie metody onBackPressed.

private class SubProgressDialog extends ProgressDialog {
    public SubProgressDialog(Context context) {
        super(context);
    }
    @Override
    public void onBackPressed() {
        /** dismiss the progress bar and clean up here **/
    }
}


public void displayProgressBar(){
    progressBar = new SubProgressDialog(this);
    progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    progressBar.setCancelable(false);
    progressBar.setMessage(getString(R.string.authorizing));        
    progressBar.show();   
    new Thread(new Runnable() {
      public void run() {
      }
       }).start();     

}

Zwróć uwagę na setCancelable (false), ponownie podkreślając, że przycisk back różni się od prostego anulowania.
Również to będzie skuteczne ignoruj wszelkie inne wejścia dotykowe od użytkownika.

 5
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-28 17:52:30

Oto moje rozwiązanie. Problem PD występuje tylko wtedy, gdy aplikacja wychodzi na przycisk Wstecz (zwykle, gdy użytkownik naciska go powtarzalnie, i tylko czasami (nie cały czas) PD jest wywoływany, gdy aplikacja już zniszczona. Odrzucenie PD onDestroy nie działa z jakiegoś powodu i kiedy próbowałem, każde naciśnięcie przycisku Wstecz zamknie aplikację, chociaż {[2] } został ustawiony na true. Zamiast tego odrzucam PD na goBack, które jest wydarzeniem, które powoduje kolizję w pierwszej kolejności, i robię to tuż przed finish(). Jeśli aplikacja kończy się na goBack normalnie nie ma problemu w pierwszej kolejności.

BTW, 'różnica' ma na celu umożliwienie użytkownikowi wyjścia z aplikacji za pomocą szybkiego podwójnego kliknięcia (400 MS między dwoma kliknięciami) zamiast wracać ze strony na stronę.

Mam nadzieję, że to komuś pomoże...
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (event.getAction() == KeyEvent.ACTION_DOWN) {
        switch (keyCode) {
        case KeyEvent.KEYCODE_BACK:
            difference = System.currentTimeMillis() - startTime;
            if (wView.canGoBack() && difference > 400) {
                wView.goBack();
            } else {
                dismissProgressDialog();
                finish();
            }
            startTime = System.currentTimeMillis();
            return true;
        }
    }
    return super.onKeyDown(keyCode, event);
}


private void dismissProgressDialog() {
   if (progressDialog != null && progressDialog.isShowing()) {
        progressDialog.dismiss();
   }
}
 3
Author: ofermc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-20 17:23:27

Javano... Przetestowałem twój scenariusz przy użyciu standardowych technik, asyncTask i ProgressDialog. W moim teście, gdy pokazuje się progressDialog i odpiszę, progressdialog jest odrzucany, a wątek w tle nadal działa. Nie wiem, dlaczego musisz zadzwonić do runOnUiThread.

Więc:

Pokaż progressDialog w onPreExecute umieść zadanie long running w doInBackground Odrzuć progresdialog w onPostExecute przekaż parametry wejściowe do swojego długotrwałego zadania jako in:

new MyAsynch().execute(password,inString);

Cancel () asynchtask i progressDialog w onPause

protected void onPause() {
    super.onPause();
    if (asynch != null) {asynch.cancel(true);}
    if (progress != null){progress.cancel();}
}

JAL

Mam tu jakiś kod .

 2
Author: JAL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-10 06:10:12

To bardzo proste, wystarczy skopiować poniższy kod i wkleić w asynchronicznym zadaniu..

ProgressDialog dialog;

@Override
protected void onPreExecute() {

    dialog = new ProgressDialog(MainActivity.this) {
        @Override
        public void onBackPressed() {
            dialog.cancel();
            dialog.dismiss();
        }
    };
    // dialog.setTitle("file is..");//its optional If u want set title in progress
    // bar
    dialog.setMessage("Loading file....");
    dialog.setCancelable(false);

    dialog.show();

}
 1
Author: Abhishek Raghuvanshi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-18 05:43:33

Postępuj zgodnie z tym, pokazuje przycisk Anuluj tylko asynchroniczne i finish wywoła, klikając przycisk Anuluj

protected void onPreExecute() {


        dialogx.setMessage("Loading... Please Wait...");
        dialogx.setCancelable(false);
        dialogx.setButton(DialogInterface.BUTTON_NEGATIVE,
                "Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

                dialogx.dismiss();
                GetDataTask.this.cancel(true);
                finish();
            }
        });
        dialogx.show();


    }
 0
Author: Ahmad Arslan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-31 11:10:02