【问题标题】:Android Back Button and Progress DialogAndroid 后退按钮和进度对话框
【发布时间】:2011-07-12 08:04:35
【问题描述】:

我有一个 AsyncTask,它在工作时显示一个 progressDialog(它从 doInBackground 中调用 runOnUiThread 来显示进度对话框)。

在运行时,我想允许使用后退按钮取消操作;其他人遇到过这个问题:BACK Button is not working ,while progressDialog is running

出于什么原因我无法回复该主题,因此不得不开始另一个?! (另一天的另一个问题)

我和桑迪有同样的想法,但是当 progressDialog 显示时,这段代码从未被调用,这是为什么呢?我已经在我的主要活动类中实现了它,progressDialog 是否暂时将前台焦点从我的类中移开?

【问题讨论】:

  • 嗯,我知道我可以覆盖 onBackPressed 但同样,这仅在 progressDialog 未运行时调用?如果我将我的 progressDialog 设置为可取消,也许我可以覆盖一个“onCancel”方法(如果有的话)?

标签: android button dialog progress back


【解决方案1】:

首先,您应该显示来自OnPreExecute 的对话框,将其隐藏在OnPostExecute 中,并在必要时通过发布进度来修改它。 (见here

现在回答您的问题: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();
                    }
                }
        );
    }

其中_progressDialogYourTaskProgressDialog 成员。

此类在 API 级别 26 中已弃用。ProgressDialog 是一种模式 对话框,它会阻止用户与应用程序交互。反而 使用此类,您应该使用进度指示器,例如 ProgressBar,可以嵌入到应用程序的 UI 中。或者, 您可以使用通知来通知用户任务的进度。 LINK

【讨论】:

  • 这是我发现的。我自己进行了更多的研究,连同你给出的答案,我已经使用你的建议使它起作用了:)
【解决方案2】:

这可以通过以下代码片段来实现:

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

progress 是 ProgressDialog 对象...

这将启用后退按钮来关闭对话框,但会阻止任何触摸输入来执行此操作...

【讨论】:

    【解决方案3】:

    嗯,我也有同样的问题。对我有用的最简单的方法是使用progressDialog.setCancelable(true).. 这声明对话框是否可以通过按返回键来取消.. 试试看,让我知道它是否适合你。祝你好运

    【讨论】:

    • 嗨 Farhan,根据 user634618 的建议,我使用了 onCancelListener() :D
    【解决方案4】:

    我刚刚找到了一个完美且最简单的解决方案来解决这个问题。 ProgressDialog中有一个方法可以设置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;
        }
    });
    

    setCancelable(false) 可以正常工作。我也在检查event.isCanceled(),因为没有它我得到了两个事件。我已经在有和没有硬件密钥的棒棒糖设备上对此进行了测试。

    【讨论】:

      【解决方案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),再次强调后退按钮不同于简单的取消。
      这也将有效地忽略来自用户的任何其他触摸输入。

      【讨论】:

      • 无需继承ProgressDialog,实现onCancelListener并使用progressDialog.setCanceledOnTouchOutside(false);以获得相同的效果。
      【解决方案6】:

      这是我的解决方案。 PD 问题仅在应用程序退出后退按钮时发生(通常是当用户重复按下它时,并且只有有时(不是所有时间)当应用程序已经销毁时才会调用 PD。关闭 PD onDestroy 不起作用出于某种原因,当我尝试过时,尽管canGoBack() 设置为true,但每次按下后退按钮都会关闭应用程序。相反,我在goBack 上关闭了PD,这是首先导致碰撞的事件,我在finish()之前就这样做了。如果应用程序在goBack上正常退出,那么首先没有问题。

      顺便说一句,“差异”旨在让用户通过快速双击(两次单击之间 400 毫秒)退出应用程序,而不是从一个页面返回到另一个页面。

      希望对某人有所帮助...

      @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。

        所以:

        在 onPreExecute 中显示 progressDialog 将长时间运行的任务放在 doInBackground 关闭 onPostExecute 中的 progressDialog 将输入参数传递给您的长时间运行的任务,如下所示:

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

        cancel() onPause 中的 asynchTask 和 progressDialog

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

        日航

        我有一些代码here

        【讨论】:

        • 是的,这正是我所追求的。设法让它与一个可中断的进度对话一起工作:)
        【解决方案8】:

        非常简单,只需复制以下代码并粘贴到异步任务中即可..

        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】:

          请按此操作,它仅显示异步取消按钮,单击取消按钮将调用完成

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

          【讨论】:

            猜你喜欢
            • 2021-11-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-08-22
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多