最近我在许多Android应用和游戏中注意到这种模式:当点击后退按钮“退出”应用时,Toast会出现类似于“请再次点击后退退出”的消息。
我在想,当我越来越频繁地看到它时,这是一个内置的功能,你可以在某个活动中访问它吗?我已经看了很多类的源代码,但我似乎找不到任何关于这一点。
当然,我可以想到一些很容易实现相同功能的方法(最简单的可能是在活动中保留一个布尔值,指示用户是否已经单击过一次…),但我想知道这里是否已经有一些东西。
编辑:正如@LAS_VEGAS所提到的,我并不是指传统意义上的“退出”。(即终止)我的意思是“回到应用程序启动活动启动之前打开的任何东西”,如果这有意义的话:)
在java中
private Boolean exit = false;
if (exit) {
onBackPressed();
}
@Override
public void onBackPressed() {
if (exit) {
finish(); // finish activity
} else {
Toast.makeText(this, "Press Back again to Exit.",
Toast.LENGTH_SHORT).show();
exit = true;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
exit = false;
}
}, 3 * 1000);
}
}
在kotlin
private var exit = false
if (exit) {
onBackPressed()
}
override fun onBackPressed(){
if (exit){
finish() // finish activity
}else{
Toast.makeText(this, "Press Back again to Exit.",
Toast.LENGTH_SHORT).show()
exit = true
Handler().postDelayed({ exit = false }, 3 * 1000)
}
}
在不得不多次实现相同的东西之后,决定是时候建立一个简单易用的库了。那是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例子
我已经尝试为此创建了一个utils类,因此任何活动或片段都可以实现这一点,从而变得更简单。
代码是用Kotlin编写的,并且具有java互操作。
我使用协程来延迟和重置标志变量。但是您可以根据自己的需要进行修改。
其他文件:SafeToast.kt
lateinit var toast: Toast
fun Context.safeToast(msg: String, length: Int = Toast.LENGTH_LONG, action: (Context) -> Toast = default) {
toast = SafeToast.makeText(this@safeToast, msg, length).apply {
// do anything new here
action(this@safeToast)
show()
}
}
fun Context.toastSpammable(msg: String) {
cancel()
safeToast(msg, Toast.LENGTH_SHORT)
}
fun Fragment.toastSpammable(msg: String) {
cancel()
requireContext().safeToast(msg, Toast.LENGTH_SHORT)
}
private val default: (Context) -> Toast = { it -> SafeToast.makeText(it, "", Toast.LENGTH_LONG) }
private fun cancel() {
if (::toast.isInitialized) toast.cancel()
}
ActivityUtils.kt
@file:JvmMultifileClass
@file:JvmName("ActivityUtils")
package your.company.com
import android.app.Activity
import your.company.com.R
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
private var backButtonPressedTwice = false
fun Activity.onBackPressedTwiceFinish() {
onBackPressedTwiceFinish(getString(R.string.msg_back_pressed_to_exit), 2000)
}
fun Activity.onBackPressedTwiceFinish(@StringRes message: Int, time: Long) {
onBackPressedTwiceFinish(getString(message), time)
}
fun Activity.onBackPressedTwiceFinish(message: String, time: Long) {
if (backButtonPressedTwice) {
onBackPressed()
} else {
backButtonPressedTwice = true
toastSpammable(message)
GlobalScope.launch {
delay(time)
backButtonPressedTwice = false
}
}
}
Kotlin中的用法
// ActivityA.kt
override fun onBackPressed() {
onBackPressedTwiceFinish()
}
在Java中使用
@Override
public void onBackPressed() {
ActivityUtils.onBackPressedTwiceFinish()
}
这段代码的灵感来自这里的@webserveis
在所有这些答案中,有一个非常简单的方法。
只需在onBackPressed()方法中编写以下代码。
long back_pressed;
@Override
public void onBackPressed() {
if (back_pressed + 1000 > System.currentTimeMillis()){
super.onBackPressed();
}
else{
Toast.makeText(getBaseContext(),
"Press once again to exit!", Toast.LENGTH_SHORT)
.show();
}
back_pressed = System.currentTimeMillis();
}
您需要将back_pressed对象定义为活动中的long。