Android - 使用toast确认应用退出

10

我是Android开发新手,希望在用户按下主活动页面上的返回按钮时出现一个Toast消息,提示“再次按下返回按钮确认退出”。我应该如何做到这一点?以下是我的进展:

@Override
public void onBackPressed() {
    // TODO Auto-generated method stub
    super.onBackPressed();
    Toast s = Toast.makeText(getBaseContext(), "Press back again to exit", Toast.LENGTH_LONG);
    s.show();
    wait();

    public boolean onBackPressed() {
        finish();    
    }
}

烤面包片是否显示?有什么问题或者没有问题?最好在其中加入一个计数器,如果计数器等于2,则完成。或者使用对话框而不是烤面包片。 - codeMagic
最佳解决方案在:https://dev59.com/-Woy5IYBdhLWcg3wnfUi - Codelaby
6个回答

21
我只会保存上次按下的时间,然后将最新一次按下的时间与之进行比较。
long lastPress;
@Override
public void onBackPressed() {
    long currentTime = System.currentTimeMillis();
    if(currentTime - lastPress > 5000){
        Toast.makeText(getBaseContext(), "Press back again to exit", Toast.LENGTH_LONG).show();
        lastPress = currentTime;
    }else{
        super.onBackPressed();
    }
}

你还可以在应用程序返回按下被确认时关闭提示(来源:@ToolmakerSteve):

long lastPress;
Toast backpressToast;
@Override
public void onBackPressed() {
    long currentTime = System.currentTimeMillis();
    if(currentTime - lastPress > 5000){
        backpressToast = Toast.makeText(getBaseContext(), "Press back again to exit", Toast.LENGTH_LONG);
        backpressToast.show();
        lastPress = currentTime;
    } else {
        if (backpressToast != null) backpressToast.cancel();
        super.onBackPressed();
    }
}

1
另外请参考user8218的改进,该改进在用户第二次按下返回键时立即删除了toast:https://dev59.com/questions/92Yr5IYBdhLWcg3wB12h#18654014。然而,user8218的答案是错误的,我在评论中解释了我的更改;希望我的更改能够被接受。 - ToolmakerSteve
@ToolmakerSteve 更新了我的答案,请确认它看起来不错。 - Heinrisch
1
看起来很棒!谢谢。现在不需要再查看user8218的答案了;这个答案已经完成了。感谢user8218提供的想法。如果你喜欢这个补充,请考虑给那个答案点赞。 - ToolmakerSteve
这里有一个备选答案可供考虑:https://dev59.com/fWw15IYBdhLWcg3wxuch#15728990。我还没有决定哪种方法更好。 - ToolmakerSteve
我对这个解决方案有两点评论。首先,LENGTH_SHORT的toast持续时间为2000ms,LENGTH_LONG的持续时间为3500ms。因此,也许最好使用相应的值而不是5000。文档说_this time could be user-definable_。我找不到如何检索实际值,这将更好。其次,如果您例如使用抽屉菜单,super.onBackPressed()将返回到上一个片段并不会退出应用程序。因此,最好明确地使用finish()关闭应用程序,而不是依赖于super.onBackPressed() - Thomas
显示剩余2条评论

3
private long mLastPress = 0;
const int TOAST_DURATION = 5000;
Toast onBackPressedToast;
@Override
public void onBackPressed() {
    long currentTime = System.currentTimeMillis();
    if (currentTime - mLastPress > TOAST_DURATION) {
        onBackPressedToast = Toast.makeText(this, R.string.press_once_again_to_exit, Toast.LENGTH_SHORT);
        onBackPressedToast.show();
        mLastPress = currentTime;
    } else {
        if (onBackPressedToast != null) {
            onBackPressedToast.cancel();  //Difference with previous answer. Prevent continuing showing toast after application exit.
            onBackPressedToast = null;
        }
        super.onBackPressed();
    }
}

在之前的回答中,Toast 只在第一次后退时创建,并且在您的回答中该 Toast 没有被取消。 - Heinrisch
可以通过在方法外部持有Toast字段来修复这个问题(根据@Heinrisch的评论):Toast onBackPressedToast;,然后将onBackPressedToast = Toast...移动到if语句内部。在else中,使用if (onBackPressedToast != null)来保护取消操作。 - ToolmakerSteve
还需要 const int TOAST_DURATION = 5000; - ToolmakerSteve
...并且在我们取消它时,最好将toast变量设置为null。 - ToolmakerSteve
@ToolmakerSteve 为什么如果应用程序将要退出,我们还需要将toast设置为null? - Thomas
@Thomas - 你说得对,鉴于我们知道应用程序正在退出,这是不必要的。(清理方法外变量的资源是一种习惯。) - ToolmakerSteve

1
在我的情况下完美运作
private static long back_pressed;

@Override
public void onBackPressed()
{
        if (back_pressed + 2000 > System.currentTimeMillis()) 
               super.onBackPressed();
        else 
             Toast.makeText(getBaseContext(), "Press once again to exit!", Toast.LENGTH_SHORT).show();
        back_pressed = System.currentTimeMillis();
}

请解释与两年前最受赞同的答案的区别。有什么不同之处,这是对那个答案的改进?此外,什么证明了将其作为新答案而不是对该答案的评论?(在我看来,将更改建议在现有答案的评论中比创建全新答案更好地服务于未来读者。) - ToolmakerSteve

0

由于多次需要实现相同的行为,决定着手构建一个专门的库:DoubleBackPress Android Library。它提供了许多易于使用的模板和无需麻烦即可实现双击返回行为。

只需执行以下操作:

// set the ToastDisplay to be shown on FirstBackPress
FirstBackPressAction firstBackPressAction = new ToastDisplay().standard(this);

// set the Action on DoubleBackPress
DoubleBackPressAction doubleBackPressAction = new DoubleBackPressAction() {
    @Override
    public void actionCall() {
        finish();
    }
};

// setup DoubleBackPress behaviour
DoubleBackPress doubleBackPress = new DoubleBackPress()
        .withDoublePressDuration(3000)
        .withFirstBackPressAction(firstBackPressAction)
        .withDoubleBackPressAction(doubleBackPressAction);

最后,使用DoubleBackPress行为覆盖onBackPressed方法以处理返回按钮的按下事件。
@Override
public void onBackPressed() {
    doubleBackPress.onBackPressed();
}

类似行为的示例GIF


0

使用Toast的最佳简单解决方案

在Java中

private Toast exitToast;

@Override
public void onBackPressed() {
    if (exitToast == null || exitToast.getView() == null || exitToast.getView().getWindowToken() == null) {
        exitToast = Toast.makeText(this, "Press again to exit", Toast.LENGTH_LONG);
        exitToast.show();
    } else {
        exitToast.cancel();
        finish();
    }
}

在 Kotlin 中
private var exitToast: Toast? = null

override fun onBackPressed() {
    if (exitToast == null || exitToast!!.view == null || exitToast!!.view.windowToken == null) {
        exitToast = Toast.makeText(this, "Press again to exit", Toast.LENGTH_LONG)
        exitToast!!.show()
    } else {
        exitToast!!.cancel()
        finish()
    }
}

0
在更新的版本中,您可以使用snackbar而不是toast。
import android.support.design.widget.Snackbar;
...
Snackbar.make(content, "Click BACK again to exit", Snackbar.LENGTH_SHORT).setAction("Action", null).show();
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接