【问题标题】:Android: Proper Way to use onBackPressed() with ToastAndroid:在 Toast 中使用 onBackPressed() 的正确方法
【发布时间】:2011-09-18 19:31:18
【问题描述】:

我编写了一段代码,它会提示用户如果他们想退出,请再次按下。我目前的代码在一定程度上可以工作,但我知道它写得不好,我认为有更好的方法来做到这一点。任何建议都会有所帮助!

代码:

public void onBackPressed(){
    backpress = (backpress + 1);
    Toast.makeText(getApplicationContext(), " Press Back again to Exit ", Toast.LENGTH_SHORT).show();

    if (backpress>1) {
        this.finish();
    }
}

【问题讨论】:

  • this.finish() 替换为super.onBackPressed();
  • 而不是this.finish() 而是调用NavUtils.navigateUpFromSameTask(this); 以返回上一个屏幕/活动

标签: android


【解决方案1】:

我会实现一个对话框,询问用户是否想退出,如果他们想退出,然后调用super.onBackPressed()

@Override
public void onBackPressed() {
    new AlertDialog.Builder(this)
        .setTitle("Really Exit?")
        .setMessage("Are you sure you want to exit?")
        .setNegativeButton(android.R.string.no, null)
        .setPositiveButton(android.R.string.yes, new OnClickListener() {

            public void onClick(DialogInterface arg0, int arg1) {
                WelcomeActivity.super.onBackPressed();
            }
        }).create().show();
}

在上面的示例中,您需要将 WelcomeActivity 替换为您的活动名称。

【讨论】:

  • 这可行,但在我的情况下,弹出窗口仅显示几毫秒,然后消失并显示新窗口。我没有时间单击是或否,如果我调试它,它不会通过 onClick 方法。为什么?
  • @Accollat​​ivo,听起来您在您的 onBackPressed() 定义中(除了 onClick 方法中的那个)还有对 super.onBackPressed() 的调用?
  • 我见过的每个应用程序都支持“第二次后压”方法。如果出现对话框,用户不小心按了返回键会很恼火。吐司的干扰较小。
  • @Steve Prentice 我在我的应用程序中使用了该 sn-p 但是如果我们在支持我们的活动时有一个正在运行的进程怎么办 - 该进程仍在运行。如何解决?如果我使用android.os.Process.killProcess(android.os.Process.myPid()); 但活动之间的动画不是那么流畅。取而代之的是,它会闪烁黑屏大约半秒。
  • @Stanimir Yakimov,查看 android 运行后台进程的服务。这将使您的生命周期管理更容易。如果您仍然无法弄清楚,我建议您创建一个新问题。
【解决方案2】:

您不需要计数器来进行后按。

只需存储对显示的 toast 的引用:

private Toast backtoast;

那么,

public void onBackPressed() {
    if(USER_IS_GOING_TO_EXIT) {
        if(backtoast!=null&&backtoast.getView().getWindowToken()!=null) {
            finish();
        } else {
            backtoast = Toast.makeText(this, "Press back to exit", Toast.LENGTH_SHORT);
            backtoast.show();
        }
    } else {
        //other stuff...
        super.onBackPressed();
    }
}

如果您在 toast 仍然可见时按下返回,并且只有在返回会导致退出应用程序时,这将调用 finish()

【讨论】:

  • 而不是this.finish() 而是调用NavUtils.navigateUpFromSameTask(this); 以返回上一个屏幕/活动
  • 考虑here的替代答案。我还没有决定我喜欢哪种方法。链接答案的一些细节可以添加到这个答案中,特别是用户退出后立即取消 toast 的逻辑。
【解决方案3】:

我使用这种更简单的方法...

public class XYZ extends Activity {
    private long backPressedTime = 0;    // used by onBackPressed()


    @Override
    public void onBackPressed() {        // to prevent irritating accidental logouts
        long t = System.currentTimeMillis();
        if (t - backPressedTime > 2000) {    // 2 secs
            backPressedTime = t;
            Toast.makeText(this, "Press back again to logout",
                                Toast.LENGTH_SHORT).show();
        } else {    // this guy is serious
            // clean up
            super.onBackPressed();       // bye
        }
    }
}

【讨论】:

  • 三星 Note 平板电脑上发生了一些奇怪的事情。需要快速回击数次。它也不喜欢“backToast”方法...
  • 在退出前取消toast会不会在Note上效果更好?见this
【解决方案4】:

你的方式和@Steve 的方式都是可以接受的防止意外退出的方式。

如果选择继续您的实施,您需要确保将 backpress 初始化为 0,并可能实施某种Timer 以在冷却时间后在按键时将其重置为 0。 (~5 秒似乎是对的)

【讨论】:

    【解决方案5】:

    您可能还需要重置onPause 中的计数器,以防止用户在第一次回按后按主页或通过其他方式导航离开的情况。否则,我看不到问题。

    【讨论】:

      【解决方案6】:

      如果你想直接从第二个活动退出你的应用程序而不去第一个活动,那么试试这个代码..`

      在第二个活动中输入这段代码..

       @Override
      public void onBackPressed() {
          new AlertDialog.Builder(this)
                  .setTitle("Really Exit?")
                  .setMessage("Are you sure you want to exit?")
                  .setNegativeButton(android.R.string.no, null)
                  .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
      
                      public void onClick(DialogInterface arg0, int arg1) {
                          setResult(RESULT_OK, new Intent().putExtra("EXIT", true));
                          finish();
                      }
      
                  }).create().show();
      }
      

      你的第一个活动把这段代码放上.....

      public class FirstActivity extends AppCompatActivity {
      
      Button next;
      private final static int EXIT_CODE = 100;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          next = (Button) findViewById(R.id.next);
          next.setOnClickListener(new View.OnClickListener() {
      
              @Override
              public void onClick(View view) {
      
                  startActivityForResult(new Intent(FirstActivity.this, SecondActivity.class), EXIT_CODE);
              }
          });
      }
      
      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          if (requestCode == EXIT_CODE) {
              if (resultCode == RESULT_OK) {
                  if (data.getBooleanExtra("EXIT", true)) {
                      finish();
                  }
              }
          }
      }
      

      }

      【讨论】:

        【解决方案7】:

        这是最好的方法,因为如果用户不返回超过两秒,则重置后压值。

        声明一个全局变量。

         private boolean backPressToExit = false;
        

        覆盖onBackPressed 方法。

        @Override
        public void onBackPressed() {
        
            if (backPressToExit) {
                super.onBackPressed();
                return;
            }
            this.backPressToExit = true;
            Snackbar.make(findViewById(R.id.yourview), getString(R.string.exit_msg), Snackbar.LENGTH_SHORT).show();
            new Handler().postDelayed(new Runnable() {
        
                @Override
                public void run() {
                    backPressToExit = false;
                }
            }, 2000);
        }
        

        【讨论】:

        • 声明一个变量,例如 private boolean backPressToExit = false
        • 1) 请编辑您的答案以包含您提到的布尔值,而不是在评论中说。所以人们可以看到声明应该在哪里。 2)事实上,这是了解时间的另一种方式。请解释为什么你认为这是“最好的”。具体来说,这会产生创建处理程序的开销——这样做会获得什么?
        【解决方案8】:

        另外,你需要在调用activity.super.onBackPressed()之前关闭对话框,否则你会得到“Activity has leaked..”错误。

        以我的 sweetalerdialog 库为例:

         @Override
            public void onBackPressed() {
                //super.onBackPressed();
                SweetAlertDialog progressDialog = new SweetAlertDialog(this, SweetAlertDialog.WARNING_TYPE);
                progressDialog.setCancelable(false);
                progressDialog.setTitleText("Are you sure you want to exit?");
                progressDialog.setCancelText("No");
                progressDialog.setConfirmText("Yes");
                progressDialog.setCanceledOnTouchOutside(true);
                progressDialog.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
                    @Override
                    public void onClick(SweetAlertDialog sweetAlertDialog) {
                        sweetAlertDialog.dismiss();
                        MainActivity.super.onBackPressed();
                    }
                });
                progressDialog.show();
            }
        

        【讨论】:

          【解决方案9】:

          使用 .onBackPressed() 来支持 Activity 指定

          @Override
          public void onBackPressed(){
              backpress = (backpress + 1);
              Toast.makeText(getApplicationContext(), " Press Back again to Exit ", Toast.LENGTH_SHORT).show();
          
              if (backpress>1) {
                  this.finish();
              }
          }
          

          【讨论】:

          • 请说明您在原始代码中添加了什么以及原因。
          【解决方案10】:

          我刚遇到这个问题并通过添加以下方法解决了它:

          @Override
          public boolean onOptionsItemSelected(MenuItem item) {
              switch (item.getItemId()) {
                  case android.R.id.home:
                       // click on 'up' button in the action bar, handle it here
                       return true;
          
                  default:
                      return super.onOptionsItemSelected(item);
              }
          }    
          

          【讨论】:

            【解决方案11】:

            您还可以使用自定义 Toast 通过以下方式使用 onBackPressed:

            enter image description here

            customized_toast.xml

            <?xml version="1.0" encoding="utf-8"?>
            <TextView
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/txtMessage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:drawableStart="@drawable/ic_white_exit_small"
                android:drawableLeft="@drawable/ic_white_exit_small"
                android:drawablePadding="8dp"
                android:paddingTop="8dp"
                android:paddingBottom="8dp"
                android:paddingLeft="16dp"
                android:paddingRight="16dp"
                android:gravity="center"
                android:textColor="@android:color/white"
                android:textSize="16sp"
                android:text="Press BACK again to exit.."
                android:background="@drawable/curve_edittext"/>
            

            MainActivity.java

            @Override
            public void onBackPressed() {
            
                if (doubleBackToExitPressedOnce) {
                    android.os.Process.killProcess(Process.myPid());
                    System.exit(1);
                    return;
                }
            
                this.doubleBackToExitPressedOnce = true;
                Toast toast = new Toast(Dashboard.this);
                View view = getLayoutInflater().inflate(R.layout.toast_view,null);
                toast.setView(view);
                toast.setDuration(Toast.LENGTH_SHORT);
                int margin = getResources().getDimensionPixelSize(R.dimen.toast_vertical_margin);
                toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_VERTICAL, 0, margin);
                toast.show();
            
                new Handler().postDelayed(new Runnable() {
            
                    @Override
                    public void run() {
                        doubleBackToExitPressedOnce=false;
                    }
                }, 2000);
            }
            

            【讨论】:

              【解决方案12】:

              使用它,它可能会有所帮助。

              @Override
              public void onBackPressed() {
                  new AlertDialog.Builder(this)
                          .setTitle("Message")
                          .setMessage("Do you want to exit app?")
                          .setNegativeButton("NO", null)
                          .setPositiveButton("YES", new DialogInterface.OnClickListener() {
                              @Override
                              public void onClick(DialogInterface dialogInterface, int i) {
                                  UserLogin.super.onBackPressed();
                              }
                          }).create().show();
              }
              

              【讨论】:

                【解决方案13】:

                按系统时间实现onBackPressed()2秒内按两次,则退出

                public class MainActivity extends AppCompatActivity {
                   private long backPressedTime;   // for back button timing less than 2 sec
                   private Toast backToast;     // to hold message of exit
                   @Override
                public void onBackPressed() {
                
                
                if (backPressedTime + 2000 > System.currentTimeMillis()) {
                
                backToast.cancel();    // abruptly cancles the toast when pressed BACK Button *back2back*
                super.onBackPressed();
                
                } else {
                
                backToast = Toast.makeText(getBaseContext(), "Press back again to exit", 
                Toast.LENGTH_SHORT);
                backToast.show();
                
                }
                backPressedTime = System.currentTimeMillis();
                
                }
                

                }

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2023-03-21
                  • 2018-01-17
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-11-09
                  相关资源
                  最近更新 更多