最近我在许多Android应用和游戏中注意到这种模式:当点击后退按钮“退出”应用时,Toast会出现类似于“请再次点击后退退出”的消息。

我在想,当我越来越频繁地看到它时,这是一个内置的功能,你可以在某个活动中访问它吗?我已经看了很多类的源代码,但我似乎找不到任何关于这一点。

当然,我可以想到一些很容易实现相同功能的方法(最简单的可能是在活动中保留一个布尔值,指示用户是否已经单击过一次…),但我想知道这里是否已经有一些东西。

编辑:正如@LAS_VEGAS所提到的,我并不是指传统意义上的“退出”。(即终止)我的意思是“回到应用程序启动活动启动之前打开的任何东西”,如果这有意义的话:)


当前回答

下面是完整的工作代码。并且不要忘记删除回调,这样它就不会在应用程序中导致内存泄漏:)

private boolean backPressedOnce = false;
private Handler statusUpdateHandler;
private Runnable statusUpdateRunnable;

public void onBackPressed() {
        if (backPressedOnce) {
            finish();
        }

        backPressedOnce = true;
        final Toast toast = Toast.makeText(this, "Press again to exit", Toast.LENGTH_SHORT);
        toast.show();

        statusUpdateRunnable = new Runnable() {
            @Override
            public void run() {
                backPressedOnce = false;
                toast.cancel();  //Removes the toast after the exit.
            }
        };

        statusUpdateHandler.postDelayed(statusUpdateRunnable, 2000);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (statusUpdateHandler != null) {
        statusUpdateHandler.removeCallbacks(statusUpdateRunnable);
    }
}

其他回答

在不得不多次实现相同的东西之后,决定是时候建立一个简单易用的库了。那是DoubleBackPress Android库。README解释了与示例一起提供的所有api(如ToastDisplay + Exit Activity),但这里有一个简短的步骤概述。


首先,在应用程序中添加依赖项:

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

接下来,在您的活动中创建一个DoubleBackPress对象,它提供所需的行为。

DoubleBackPress doubleBackPress = new DoubleBackPress();
doubleBackPress.setDoublePressDuration(3000);           // msec

然后创建一个Toast,需要在第一次背压时显示。在这里,您可以创建自己的Toast,或者使用库中提供的标准吐司。通过后面的选项来实现。

FirstBackPressAction firstBackPressAction = new ToastDisplay().standard(this);
doubleBackPress.setFirstBackPressAction(firstBackPressAction);   // set the action

现在,定义当你第二次背推发生时应该发生什么。在这里,我们正在关闭Activity。

DoubleBackPressAction doubleBackPressAction = new DoubleBackPressAction() {
    @Override
    public void actionCall() {
        finish();
        System.exit(0);
    }
};

最后,用DoubleBackPress行为覆盖你的背压行为。

@Override
public void onBackPressed() {
    doubleBackPress.onBackPressed();
}

类似行为要求的GIF例子

private static final int TIME_INTERVAL = 2000;
private long mBackPressed;
    @Override
        public void onBackPressed() {

            if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis()) {
                super.onBackPressed();
                Intent intent = new Intent(FirstpageActivity.this,
                        HomepageActivity.class);
                startActivity(intent);
                finish();

                return;
            } else {

                Toast.makeText(getBaseContext(),
                        "Tap back button twice  to go Home.", Toast.LENGTH_SHORT)
                        .show();

                mBackPressed = System.currentTimeMillis();

            }

        }

我认为这是你需要的,我的意思是,当我们想要显示这个吐司时,当堆栈中只有一个活动时用户从堆栈的最后一个活动中返回。

var exitOpened=false // Declare it globaly

在onBackPressed方法中修改如下:

override fun onBackPressed() {
        if (isTaskRoot && !exitOpened)
        {
            exitOpened=true
            toast("Please press back again to exit")
            return
        }
        super.onBackPressed()
    }

在这里,如果当前活动是堆栈的根活动(第一个活动),isTaskRoot将返回true,如果不是,则返回false。

你可以在这里查看官方文件

它不是内置的功能。我认为这甚至不是被推荐的行为。Android应用程序并不意味着退出:

为什么Android应用程序不提供“退出”选项?

为MainActivity类声明一个全局Toast变量。示例:Toast exitToast; 在onCreate视图方法中初始化它。例子: exitToast = Toast.makeText(getApplicationContext(), "Press back again to exit", Toast.LENGTH_SHORT); 最后创建一个onBackPressedMethod,如下所示: @Override onBackPressed() { if (exitToast.getView(). isshow ()) { exitToast.cancel (); 完成(); }其他{ exitToast.show (); } }

这工作正确,我已经测试过了。我认为这样更简单。