最近我在许多Android应用和游戏中注意到这种模式:当点击后退按钮“退出”应用时,Toast会出现类似于“请再次点击后退退出”的消息。
我在想,当我越来越频繁地看到它时,这是一个内置的功能,你可以在某个活动中访问它吗?我已经看了很多类的源代码,但我似乎找不到任何关于这一点。
当然,我可以想到一些很容易实现相同功能的方法(最简单的可能是在活动中保留一个布尔值,指示用户是否已经单击过一次…),但我想知道这里是否已经有一些东西。
编辑:正如@LAS_VEGAS所提到的,我并不是指传统意义上的“退出”。(即终止)我的意思是“回到应用程序启动活动启动之前打开的任何东西”,如果这有意义的话:)
我已经尝试为此创建了一个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
在不得不多次实现相同的东西之后,决定是时候建立一个简单易用的库了。那是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例子
我用这个
import android.app.Activity;
import android.support.annotation.StringRes;
import android.widget.Toast;
public class ExitApp {
private static long lastClickTime;
public static void now(Activity ctx, @StringRes int message) {
now(ctx, ctx.getString(message), 2500);
}
public static void now(Activity ctx, @StringRes int message, long time) {
now(ctx, ctx.getString(message), time);
}
public static void now(Activity ctx, String message, long time) {
if (ctx != null && !message.isEmpty() && time != 0) {
if (lastClickTime + time > System.currentTimeMillis()) {
ctx.finish();
} else {
Toast.makeText(ctx, message, Toast.LENGTH_SHORT).show();
lastClickTime = System.currentTimeMillis();
}
}
}
}
使用到事件onBackPressed
@Override
public void onBackPressed() {
ExitApp.now(this,"Press again for close");
}
或ExitApp.now(这个,R.string.double_back_pressed)
对于需要关闭的更改秒,指定毫秒
ExitApp.now (R.string.double_back_pressed, 5000)