如何显示对话框以确认用户希望退出Android活动?
我一直在尝试在用户试图退出活动时显示“是否要退出?”类型的对话框如何显示对话框以确认用户希望退出Android活动?,android,android-activity,android-dialog,activity-finish,Android,Android Activity,Android Dialog,Activity Finish,我一直在尝试在用户试图退出活动时显示“是否要退出?”类型的对话框 但是,我找不到合适的API挂钩Activity.onUserLeaveHint()最初看起来很有希望,但我找不到阻止活动完成的方法。在Android 2.0+中,这看起来像: @Override public void onBackPressed() { new AlertDialog.Builder(this) .setIcon(android.R.drawable.ic_dialog_alert)
但是,我找不到合适的API挂钩
Activity.onUserLeaveHint()
最初看起来很有希望,但我找不到阻止活动完成的方法。在Android 2.0+中,这看起来像:
@Override
public void onBackPressed() {
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Closing Activity")
.setMessage("Are you sure you want to close this activity?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setNegativeButton("No", null)
.show();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//Handle the back button
if(keyCode == KeyEvent.KEYCODE_BACK) {
//Ask the user if they want to quit
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.quit)
.setMessage(R.string.really_quit)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Stop the activity
YourClass.this.finish();
}
})
.setNegativeButton(R.string.no, null)
.show();
return true;
}
else {
return super.onKeyDown(keyCode, event);
}
}
在早期版本中,它看起来像:
@Override
public void onBackPressed() {
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Closing Activity")
.setMessage("Are you sure you want to close this activity?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setNegativeButton("No", null)
.show();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//Handle the back button
if(keyCode == KeyEvent.KEYCODE_BACK) {
//Ask the user if they want to quit
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.quit)
.setMessage(R.string.really_quit)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Stop the activity
YourClass.this.finish();
}
})
.setNegativeButton(R.string.no, null)
.show();
return true;
}
else {
return super.onKeyDown(keyCode, event);
}
}
已修改@user919216代码。。并使其与WebView兼容
@Override
public void onBackPressed() {
if (webview.canGoBack()) {
webview.goBack();
}
else
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
如果您不确定对“后退”的呼叫是否会退出应用程序,或者是否会将用户带到另一个活动,您可以将上述答案包装在一个复选框isTaskRoot()中。如果主活动可以多次添加到后台堆栈,或者如果您正在处理后台堆栈历史记录,则可能会发生这种情况
if(isTaskRoot()) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
YourActivity.super.onBackPressed;
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
} else {
super.onBackPressed();
}
我更喜欢双击后退按钮退出,而不是退出对话框 在这个解决方案中,它会在第一次返回时显示一个祝酒词,警告再次按下将关闭应用程序。在本例中,小于4秒
private Toast toast;
private long lastBackPressTime = 0;
@Override
public void onBackPressed() {
if (this.lastBackPressTime < System.currentTimeMillis() - 4000) {
toast = Toast.makeText(this, "Press back again to close this app", 4000);
toast.show();
this.lastBackPressTime = System.currentTimeMillis();
} else {
if (toast != null) {
toast.cancel();
}
super.onBackPressed();
}
}
私人吐司;
私人长时间lastBackPressTime=0;
@凌驾
public void onBackPressed(){
if(this.lastBackPressTime
来自的标记:我喜欢@GLee方法,并将其与下面的片段一起使用
@Override
public void onBackPressed() {
if(isTaskRoot()) {
new ExitDialogFragment().show(getSupportFragmentManager(), null);
} else {
super.onBackPressed();
}
}
使用片段的对话框:
public class ExitDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.exit_question)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
getActivity().finish();
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
getDialog().cancel();
}
})
.create();
}
}
使用Lambda:
new AlertDialog.Builder(this).setMessage(getString(R.string.exit_msg))
.setTitle(getString(R.string.info))
.setPositiveButton(getString(R.string.yes), (arg0, arg1) -> {
moveTaskToBack(true);
finish();
})
.setNegativeButton(getString(R.string.no), (arg0, arg1) -> {
})
.show();
您还需要在gradle.build中设置级别语言以支持java 8:
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
在中国,大多数应用程序会通过“点击两次”确认退出:
boolean doublebacktoexit pressedonce=false;
@凌驾
public void onBackPressed(){
如果(DoubleBacktoExit按Donce){
super.onBackPressed();
返回;
}
this.doublebacktoexit pressedonce=true;
Toast.makeText(这是“请再次单击返回退出”,Toast.LENGTH_SHORT.show();
new Handler().postDelayed(new Runnable()){
@凌驾
公开募捐{
DoubleBackToExit PresseDonce=false;
}
}, 2000);
}
首先删除super.onBackPressed()代码>来自onbackPressed()
方法,代码如下:
@Override
public void onBackPressed() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MyActivity.this.finish();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
另一种选择是在第一次按back键时显示一个Toast
/Snackbar
,要求再次按back键退出,这比显示一个AlertDialog
来确认用户是否要退出应用程序的干扰小得多
您可以使用通过几行代码来实现这一点
首先,将依赖项添加到应用程序中:
dependencies {
implementation 'com.github.kaushikthedeveloper:double-back-press:0.0.1'
}
接下来,在您的活动中,实施所需的行为
// set the Toast to be shown on FirstBackPress (ToastDisplay - builtin template)
// can be replaced by custom action (new FirstBackPressAction{...})
FirstBackPressAction firstBackPressAction = new ToastDisplay().standard(this);
// set the Action on DoubleBackPress
DoubleBackPressAction doubleBackPressAction = new DoubleBackPressAction() {
@Override
public void actionCall() {
// TODO : Exit the application
finish();
System.exit(0);
}
};
// setup DoubleBackPress behaviour : close the current Activity
DoubleBackPress doubleBackPress = new DoubleBackPress()
.withDoublePressDuration(3000) // msec - wait for second back press
.withFirstBackPressAction(firstBackPressAction)
.withDoubleBackPressAction(doubleBackPressAction);
最后,将此设置为背压时的行为
@Override
public void onBackPressed() {
doubleBackPress.onBackPressed();
}
你有这个提示是绝对必要的吗?当用户想要完成一项活动时,他们应该能够立即完成。您可能需要重新考虑您的策略。在三星应用商店登录时,必须显示退出确认选项。我的一个应用因为没有这个被拒绝了。这很讨厌,@Samsung。这取决于你退出后想做什么。如果状态被保留,并且您可以返回,则可能不需要显示对话框。然而,在我的一个应用程序中,我最终提交了数据,从而彻底清理了cookie、数据和紧密连接。应该让用户意识到他们选择的最终性,特别是因为在今天的移动应用程序中,这种最终性的感觉并不常见。@Tom R:完全不同意。有些应用程序是你不想意外完成的。在2.0及以上版本中,还有一个新的onBackPressed事件建议使用onKeyDown。这里有一节讨论了更改和新的推荐方法。关于在此处捕获back键的博客文章:请注意,这不允许您捕获用户可以离开应用程序的其他方式:按home键、选择通知、接听电话等。这非常有效,但如何在向用户显示代码时强制停止代码执行?找到了,这是一个很好的解决方案:这是我正在寻找的方法(),但我不知道在哪里调用此方法()。elBradford发表了评论:调用超级onBackPressed比假设onBackPressed只调用finish()要好。即使现在是这样,在未来的API中也可能不是这样的CustomTabActivity.super.onBackPressed
@mplungjan您能澄清一下您的评论吗。。。你是说最好用super.onBackPressed()
替换finish()。我不知道什么是好的实践2015@mplungjan你的评论提到了未来的API,但如果你能澄清一下,这将是很有帮助的。没有问题。嗯,我刚刚尝试了MyActivity.super.onBackPressed()代码>对我来说很好。这似乎也是最合乎逻辑的方法——当用户点击“否”时,如果您想要标准的行为,则调用您要覆盖的方法。这一方法无疑是我的最爱,因为对话框可能会很麻烦。我稍微改了一下,改为3秒,用那个记号笔看起来更自然了。感谢您的帖子。如果我退出,请按双后退按钮,但在我的代码中,它打开了一个登录活动(表示启用微调器的后退活动)y第一个活动,我不能将其放在中间的活动中。因为现在它jsut关闭了当前的活动,并显示了以前的一次搜索。非常感谢。我认为这必须被标记为答案。其他的没用。我正在搜索isTaskRoot()方法所具有的功能。