Подтвердить что ты не робот

Android Back Button и Progress Dialog

У меня есть AsyncTask, который показывает progressDialog во время работы (он вызывает runOnUiThread изнутри doInBackground, чтобы отобразить диалог выполнения).

Пока он работает, я хочу разрешить использование кнопки "Назад" для отмены операции; у кого-то была эта проблема: Кнопка BACK не работает, а progressDialog работает

По какой причине я не могу ответить на этот поток, поэтому нужно начать с другого?! (Еще один вопрос за другой день)

У меня была такая же идея, как у Sandy, но этот код никогда не вызывается, пока показывает прогрессDialog, почему это? Я внедрил его в свой основной класс активности, разве progressDialog временно отвлекает фокус от моего класса?

4b9b3361

Ответ 1

Сначала вы должны показать свое диалоговое окно от OnPreExecute, скрыть его в OnPostExecute и - при необходимости - изменить его, опубликовав ход. (см. здесь)

Теперь на ваш вопрос: ProgressDialog.show() может принимать OnCancelListener в качестве аргумента. Вы должны указать тот, который вызывает cancel() в экземпляре диалогового окна выполнения.

Пример:

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

где _progressDialog является членом ProgressDialog YourTask.

Ответ 2

Хорошо, у меня была такая же проблема. Самый простой метод, который работал у меня, - это использовать progressDialog.setCancelable(true).. Это объявляет, отменяется ли диалог, нажав на задний ключ. Попробуйте и сообщите мне, работает ли оно для вас или нет. Удачи.

Ответ 3

Это может быть достигнуто с помощью следующего фрагмента кода:

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

прогресс - это объект ProgressDialog...

Это позволит кнопке "Назад" закрыть диалоговое окно, но не позволяет использовать любой сенсорный ввод...

Ответ 4

Я нашел идеальное и простое решение этой проблемы. Для установки KeyListener существует метод ProgressDialog.

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

Он отлично работает с setCancelable(false). Я также проверяю event.isCanceled(), потому что без этого я получаю два события. Я тестировал это на устройстве Lollipop с помощью и без аппаратных клавиш.

Ответ 5

Лечение обратной кнопки, как отмены, не является правильным способом.
Отмена также происходит, когда пользователь касается экрана вне диалогового окна. Вы хотите отличить эти два действия, нет?

Правильный подход заключается в расширении класса ProgressDialog и переопределении метода 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();     

}

Обратите внимание на setCancelable (false), снова подчеркивая, что кнопка возврата отличается от простой отмены.
Также это будет эффективно игнорировать любые другие сенсорные входы от пользователя.

Ответ 6

Вот мое решение. Проблема с PD возникает только тогда, когда приложение выходит из кнопки "Назад" (обычно, когда пользователь нажимает ее повторно, и только иногда (не все время) PD вызывается, когда приложение уже уничтожено. Отказ от PD onDestroy не работает по какой-то причине, и когда я это пробовал, каждое нажатие кнопки "Назад" закроет приложение, хотя для параметра canGoBack() установлено значение true. Вместо этого я отклоняю PD на goBack, который является событием, которое вызывает столкновение в первую очередь, и я делаю это прямо перед finish(). Если приложение выходит на goBack, как правило, там нет проблем в первую очередь.

BTW, "разница" нацелена на то, чтобы позволить пользователю выйти из приложения с быстрым двойным щелчком (400 MS между двумя щелчками мыши), вместо того, чтобы возвращаться со страницы на страницу.

Надеюсь, что это поможет кому-то...

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

Ответ 7

javano... Я протестировал ваш сценарий, используя стандартные методы, asyncTask и ProgressDialog. В моем тесте, когда progressDialog отображается, и я ударяю назад, progressdialog отклоняется и фоновый поток продолжает работать. Я не знаю, почему вам нужно вызвать runOnUiThread.

SO:

показать прогрессDialog в onPreExecute поместите долгое задание в doInBackground отклонить progressDialog в onPostExecute передайте входные параметры в свою длительную задачу, как в:

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

cancel() asynchTask и progressDialog в onPause

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

JAL

У меня есть код здесь.

Ответ 8

Его очень просто скопировать приведенный ниже код и вставить в задачу Async.

Диалоговое окно ProgressDialog;

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

}

Ответ 9

Пожалуйста, следуйте этому, он показывает кнопку отмены только async, и завершение вызовет, нажав кнопку отмены

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


    }