如何显示一个对话框来确认用户希望退出 Android Activity?

问题描述 投票:0回答:11

我一直试图表现出“你想退出吗?”当用户尝试退出活动时的对话框类型。

但是我找不到合适的 API 挂钩。

Activity.onUserLeaveHint()
最初看起来很有希望,但我找不到阻止 Activity 完成的方法。

android android-activity android-dialog activity-finish
11个回答
402
投票

在 Android 2.0+ 中,这看起来像:

@Override
public void onBackPressed() {
    new AlertDialog.Builder(this)
        .setIconAttribute(android.R.attr.alertDialogIcon)
        .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);
    }
    
}

191
投票
@Override
public void onBackPressed() {
    new AlertDialog.Builder(this)
           .setMessage("Are you sure you want to exit?")
           .setCancelable(false)
           .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   ExampleActivity.super.onBackPressed();
               }
           })
           .setNegativeButton("No", null)
           .show();
}

33
投票

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

}

26
投票

我更愿意通过双击后退按钮退出,而不是使用退出对话框。

在此解决方案中,第一次返回时会显示一个吐司,警告再次按后退将关闭应用程序。在此示例中不到 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();
 }
}

令牌来自:http://www.androiduipatterns.com/2011/03/back-button-behavior.html


22
投票

如果您不确定调用“back”是否会退出应用程序,或者会将用户带到另一个活动,您可以将上述答案包装在检查 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();
}

7
投票

在中国,大多数App都会通过“点击两次”来确认退出:

boolean doubleBackToExitPressedOnce = false;

@Override
public void onBackPressed() {
    if (doubleBackToExitPressedOnce) {
        super.onBackPressed();
        return;
    }

    this.doubleBackToExitPressedOnce = true;
    Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();

    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            doubleBackToExitPressedOnce=false;                       
        }
    }, 2000);
} 

6
投票

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

6
投票

首先从

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

}

4
投票
Just put this code in your first activity 

@Override
    public void onBackPressed() {
        if (drawerLayout.isDrawerOpen(GravityCompat.END)) {
            drawerLayout.closeDrawer(GravityCompat.END);
        }
        else {
// if your using fragment then you can do this way
            int fragments = getSupportFragmentManager().getBackStackEntryCount();
            if (fragments == 1) {
new AlertDialog.Builder(this)
           .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", null)
           .show();


            } else {
                if (getFragmentManager().getBackStackEntryCount() > 1) {
                    getFragmentManager().popBackStack();
                } else {

           super.onBackPressed();
                }
            }
        }
    }

2
投票

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

1
投票

另一种选择是在第一次返回时显示 Toast

/
Snackbar
,要求再次按回退出
,这比显示
AlertDialog
 来确认用户是否要退出要少得多。应用程序。

您可以使用

DoubleBackPress Android Library

 通过几行代码来实现此目的。 显示类似行为的示例 GIF。

首先,将依赖项添加到您的应用程序中:

dependencies { implementation 'com.github.kaushikthedeveloper:double-back-press:0.0.1' }


接下来,在您的 Activity 中实现所需的行为。

// 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(); }
    
© www.soinside.com 2019 - 2024. All rights reserved.