Android: 使用 onBackPress()和 Toast 的正确方法

我编写了一段代码,它会给用户一个提示,要求他们如果想退出就再次按回。目前我的代码在一定程度上可以正常工作,但我知道它写得很糟糕,我认为有更好的方法可以做到这一点。任何建议都会有帮助的!

密码:

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


if (backpress>1) {
this.finish();
}
}
278175 次浏览

I would implement a dialog asking the user if they wanted to exit and then call super.onBackPressed() if they did.

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

In the above example, you'll need to replace WelcomeActivity with the name of your activity.

Both your way and @Steve's way are acceptable ways to prevent accidental exits.

If choosing to continue with your implementation, you will need to make sure to have backpress initialized to 0, and probably implement a Timer of some sort to reset it back to 0 on keypress, after a cooldown period. (~5 seconds seems right)

You may also need to reset counter in onPause to prevent cases when user presses home or navigates away by some other means after first back press. Otherwise, I don't see an issue.

You don't need a counter for back presses.

Just store a reference to the toast that is shown:

private Toast backtoast;

Then,

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

This will call finish() if you press back while the toast is still visible, and only if the back press would result in exiting the application.

I use this much simpler approach...

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

This is the best way, because if user not back more than two seconds then reset backpressed value.

declare one global variable.

 private boolean backPressToExit = false;

Override onBackPressed Method.

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

additionally, you need to dissmis dialog before calling activity.super.onBackPressed(), otherwise you'll get "Activity has leaked.." error.

Example in my case with sweetalerdialog library:

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

use to .onBackPressed() to back Activity specify

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


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

I just had this issue and solved it by adding the following method:

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

You can also use onBackPressed by following ways using customized Toast:

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

If you want to exit your application from direct Second Activity without going to First Activity then try this code..`

In Second Activity put this code..

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

And Your First Activity Put this code.....

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

}

Use this, it may help.

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

implementing onBackPressed() by System time, if pressed twice within 2 sec, then will exit

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


}

}