我最近在很多Android应用和游戏中都注意到了这种模式:当点击后退按钮“退出”应用程序时,Toast
会出现类似于“请再次点击返回”的消息退出”。
我想知道,因为我越来越频繁地看到它是一个内置功能,你可以以某种方式访问活动?我查看了许多类的源代码,但我似乎无法找到任何相关内容。
当然,我可以考虑几种方法来轻松实现相同的功能(最简单的可能是在活动中保留一个布尔值,表明用户是否已经点击过一次......)但是我想知道是否有已有的东西。
编辑:正如@LAS_VEGAS所提到的,我并不是指传统意义上的“退出”。 (即终止)我的意思是“回到应用程序启动活动启动之前打开的任何内容”,如果这有意义的话:)
答案 0 :(得分:844)
在Java活动中:
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);
}
在Kotlin活动中:
private var doubleBackToExitPressedOnce = false
override fun onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed()
return
}
this.doubleBackToExitPressedOnce = true
Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show()
Handler().postDelayed(Runnable { doubleBackToExitPressedOnce = false }, 2000)
}
我认为这个处理程序有助于在2秒后重置变量。
答案 1 :(得分:204)
Sudheesh B Nair在这个问题上有一个很好的(并且被接受的)答案,我认为应该有更好的选择,例如;
测量时间过去有什么不对,并检查自上次背压后是否TIME_INTERVAL
毫秒(比如2000)。以下示例代码使用System.currentTimeMillis();
来存储调用时间onBackPressed()
;
private static final int TIME_INTERVAL = 2000; // # milliseconds, desired time passed between two back presses.
private long mBackPressed;
@Override
public void onBackPressed()
{
if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis())
{
super.onBackPressed();
return;
}
else { Toast.makeText(getBaseContext(), "Tap back button in order to exit", Toast.LENGTH_SHORT).show(); }
mBackPressed = System.currentTimeMillis();
}
回到接受的答案批判;使用 flag
指示是否在最后TIME_INTERVAL
(例如2000)毫秒内按下了设置 - 重置是通过Handler
postDelayed()
方法是我想到的第一件事。但是,当活动结束时,应取消postDelayed()
操作,删除Runnable
。
为了删除Runnable
,不得将其声明为匿名,并将其与Handler
一起声明为成员。然后可以适当地调用removeCallbacks()
Handler
方法。
以下示例是演示;
private boolean doubleBackToExitPressedOnce;
private Handler mHandler = new Handler();
private final Runnable mRunnable = new Runnable() {
@Override
public void run() {
doubleBackToExitPressedOnce = false;
}
};
@Override
protected void onDestroy()
{
super.onDestroy();
if (mHandler != null) { mHandler.removeCallbacks(mRunnable); }
}
@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();
mHandler.postDelayed(mRunnable, 2000);
}
感谢@NSouth的贡献;为了防止在应用程序关闭后出现 toast message ,可以将Toast
声明为成员 - 比如mExitToast
- 并且可以通过mExitToast.cancel();
取消就在super.onBackPressed();
致电之前。
答案 2 :(得分:29)
想到我最后会分享我是如何做到的,我刚刚加入了我的活动:
private boolean doubleBackToExitPressedOnce = false;
@Override
protected void onResume() {
super.onResume();
// .... other stuff in my onResume ....
this.doubleBackToExitPressedOnce = false;
}
@Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, R.string.exit_press_back_twice_message, Toast.LENGTH_SHORT).show();
}
它完全符合我的要求。包括在恢复活动时重置状态。
答案 3 :(得分:23)
流程图:
Java代码:
private long lastPressedTime;
private static final int PERIOD = 2000;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
switch (event.getAction()) {
case KeyEvent.ACTION_DOWN:
if (event.getDownTime() - lastPressedTime < PERIOD) {
finish();
} else {
Toast.makeText(getApplicationContext(), "Press again to exit.",
Toast.LENGTH_SHORT).show();
lastPressedTime = event.getEventTime();
}
return true;
}
}
return false;
}
答案 4 :(得分:18)
所有这些答案中都有最简单的方法。
只需在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
。
答案 5 :(得分:12)
根据评论中的正确答案和建议,我创建了一个完全正常的演示,并在使用后删除了处理程序回调。
<强> MainActivity.java 强>
package com.mehuljoisar.d_pressbacktwicetoexit;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final long delay = 2000L;
private boolean mRecentlyBackPressed = false;
private Handler mExitHandler = new Handler();
private Runnable mExitRunnable = new Runnable() {
@Override
public void run() {
mRecentlyBackPressed=false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onBackPressed() {
//You may also add condition if (doubleBackToExitPressedOnce || fragmentManager.getBackStackEntryCount() != 0) // in case of Fragment-based add
if (mRecentlyBackPressed) {
mExitHandler.removeCallbacks(mExitRunnable);
mExitHandler = null;
super.onBackPressed();
}
else
{
mRecentlyBackPressed = true;
Toast.makeText(this, "press again to exit", Toast.LENGTH_SHORT).show();
mExitHandler.postDelayed(mExitRunnable, delay);
}
}
}
我希望它会有所帮助!!
答案 6 :(得分:11)
我使用snackbar的解决方案:
Snackbar mSnackbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final LinearLayout layout = findViewById(R.id.layout_main);
mSnackbar = Snackbar.make(layout, R.string.press_back_again, Snackbar.LENGTH_SHORT);
}
@Override
public void onBackPressed() {
if (mSnackbar.isShown()) {
super.onBackPressed();
} else {
mSnackbar.show();
}
}
简单而时尚。
答案 7 :(得分:10)
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);
声明变量 private boolean doubleBackToExitPressedOnce = false;
将其粘贴到您的主要活动中,这将解决您的问题
答案 8 :(得分:9)
退出应用程序时使用Runnable并不是一个好主意,我最近想出了一种更简单的方法来记录和比较两个BACK按钮点击之间的时间。示例代码如下:
private static long back_pressed_time;
private static long PERIOD = 2000;
@Override
public void onBackPressed()
{
if (back_pressed_time + PERIOD > System.currentTimeMillis()) super.onBackPressed();
else Toast.makeText(getBaseContext(), "Press once again to exit!", Toast.LENGTH_SHORT).show();
back_pressed_time = System.currentTimeMillis();
}
这样就可以通过双重BACK按钮在一定的延迟时间内点击退出应用程序,该延迟时间为2000毫秒。
答案 9 :(得分:6)
接受的答案是最佳答案,但如果您使用 Android Design Support Library
,则可以使用SnackBar
获取更好的观看次数。
boolean doubleBackToExitPressedOnce = false;
@Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Snackbar.make(findViewById(R.id.photo_album_parent_view), "Please click BACK again to exit", Snackbar.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
答案 10 :(得分:6)
最后创建一个onBackPressedMethod作为Follows:
@Override
public void onBackPressed() {
if (exitToast.getView().isShown()) {
exitToast.cancel();
finish();
} else {
exitToast.show();
}
}
这个工作正常,我已经测试过了。我认为这更简单。
答案 11 :(得分:6)
它不是内置功能。我认为这甚至不是推荐的行为。 Android应用无意退出:
答案 12 :(得分:5)
Zefnus使用System.currentTimeMillis()的答案是最好的(+1)。我这样做的方式是不比这更好,但仍然发布它以增加上述想法。
如果按下后退按钮时看不到吐司,则显示吐司,而如果可见(后退已在最后Toast.LENGTH_SHORT
时间内按下一次),则退出。 / p>
exitToast = Toast.makeText(this, "Press again to exit", Toast.LENGTH_SHORT);
.
.
@Override
public void onBackPressed() {
if (exitToast.getView().getWindowToken() == null) //if toast is currently not visible
exitToast.show(); //then show toast saying 'press againt to exit'
else { //if toast is visible then
finish(); //or super.onBackPressed();
exitToast.cancel();
}
}
答案 13 :(得分:5)
最近,我需要在我的应用程序中实现这个后退按钮功能。原始问题的答案很有用,但我还需要考虑两点:
根据答案和评论,我创建了以下代码:
private static final long BACK_PRESS_DELAY = 1000;
private boolean mBackPressCancelled = false;
private long mBackPressTimestamp;
private Toast mBackPressToast;
@Override
public void onBackPressed() {
// Do nothing if the back button is disabled.
if (!mBackPressCancelled) {
// Pop fragment if the back stack is not empty.
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
super.onBackPressed();
} else {
if (mBackPressToast != null) {
mBackPressToast.cancel();
}
long currentTimestamp = System.currentTimeMillis();
if (currentTimestamp < mBackPressTimestamp + BACK_PRESS_DELAY) {
super.onBackPressed();
} else {
mBackPressTimestamp = currentTimestamp;
mBackPressToast = Toast.makeText(this, getString(R.string.warning_exit), Toast.LENGTH_SHORT);
mBackPressToast.show();
}
}
}
}
上面的代码假定使用了支持库。如果您使用片段但不使用支持库,则需要将getSupportFragmentManager()
替换为getFragmentManager()
。
如果永远不会取消后退按钮,请删除第一个if
。如果您不使用片段或片段后栈,则删除第二个if
此外,请务必注意自Android 2.0以来支持方法onBackPressed
。请查看this page以获取详细说明。要使背压功能也适用于旧版本,请将以下方法添加到您的活动中:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR
&& keyCode == KeyEvent.KEYCODE_BACK
&& event.getRepeatCount() == 0) {
// Take care of calling this method on earlier versions of
// the platform where it doesn't exist.
onBackPressed();
}
return super.onKeyDown(keyCode, event);
}
答案 14 :(得分:4)
我知道这是一个非常古老的问题,但这是做你想做的最简单的方法。
@Override
public void onBackPressed() {
++k; //initialise k when you first start your activity.
if(k==1){
//do whatever you want to do on first click for example:
Toast.makeText(this, "Press back one more time to exit", Toast.LENGTH_LONG).show();
}else{
//do whatever you want to do on the click after the first for example:
finish();
}
}
我知道这不是最好的方法,但它运作正常!
答案 15 :(得分:3)
在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)
}
}
答案 16 :(得分:3)
当您将先前的堆栈活动存储在堆栈中时,这也会有所帮助。
我修改了Sudheesh的回答
boolean doubleBackToExitPressedOnce = false;
@Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
//super.onBackPressed();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//***Change Here***
startActivity(intent);
finish();
System.exit(0);
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);
}
答案 17 :(得分:2)
这是完整的工作代码。并且不要忘记删除回调,以免它在应用程序中导致内存泄漏。 :)
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);
}
}
答案 18 :(得分:2)
在这里,我已经概括地编写了N个抽头计数的代码。该代码类似于Android设备手机中的Enable Developer选项编写。即使你可以在开发人员测试应用程序时使用它来启用功能。
private Handler tapHandler;
private Runnable tapRunnable;
private int mTapCount = 0;
private int milSecDealy = 2000;
onCreate(){
...
tapHandler = new Handler(Looper.getMainLooper());
}
在backpress或logout选项上调用 askToExit()。
private void askToExit() {
if (mTapCount >= 2) {
releaseTapValues();
/* ========= Exit = TRUE ========= */
}
mTapCount++;
validateTapCount();
}
/* Check with null to avoid create multiple instances of the runnable */
private void validateTapCount() {
if (tapRunnable == null) {
tapRunnable = new Runnable() {
@Override
public void run() {
releaseTapValues();
/* ========= Exit = FALSE ========= */
}
};
tapHandler.postDelayed(tapRunnable, milSecDealy);
}
}
private void releaseTapValues() {
/* Relase the value */
if (tapHandler != null) {
tapHandler.removeCallbacks(tapRunnable);
tapRunnable = null; /* release the object */
mTapCount = 0; /* release the value */
}
}
@Override
protected void onDestroy() {
super.onDestroy();
releaseTapValues();
}
答案 19 :(得分:2)
为此,我实现了以下功能:
private long onRecentBackPressedTime;
@Override
public void onBackPressed() {
if (System.currentTimeMillis() - onRecentBackPressedTime > 2000) {
onRecentBackPressedTime = System.currentTimeMillis();
Toast.makeText(this, "Please press BACK again to exit", Toast.LENGTH_SHORT).show();
return;
}
super.onBackPressed();
}
答案 20 :(得分:2)
@Override public void onBackPressed() {
Log.d("CDA", "onBackPressed Called");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
}
答案 21 :(得分:1)
Sudheesh B Nair的答案中的一些改进,我注意到它会等待处理程序,即使在立即按下两次,所以取消处理程序,如下所示。我已经用tocled toast来阻止它在app退出后显示。
boolean doubleBackToExitPressedOnce = false;
Handler myHandler;
Runnable myRunnable;
Toast myToast;
@Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
myHandler.removeCallbacks(myRunnable);
myToast.cancel();
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
myToast = Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT);
myToast.show();
myHandler = new Handler();
myRunnable = new Runnable() {
@Override
public void run() {
doubleBackToExitPressedOnce = false;
}
};
myHandler.postDelayed(myRunnable, 2000);
}
答案 22 :(得分:1)
此解决方案的独特之处在于行为;在关闭应用程序时,非双击将显示吐司,而成功双击将不显示吐司。 唯一的缺点是烤面包片的显示将有650毫秒的延迟。我相信这是具有最佳行为的最佳解决方案,因为逻辑表明没有这种延迟就不可能有这种行为
//App Closing Vars
private var doubleBackPressedInterval: Long = 650
private var doubleTap = false
private var pressCount = 0
private var timeLimit: Long = 0
override fun onBackPressed() {
pressCount++
if(pressCount == 1) {
timeLimit = System.currentTimeMillis() + doubleBackPressedInterval
if(!doubleTap) {
showExitInstructions()
}
}
if(pressCount == 2) {
if(timeLimit > System.currentTimeMillis()) {
doubleTap = true
super.onBackPressed()
}
else {
showExitInstructions()
}
pressCount = 1
timeLimit = System.currentTimeMillis() + doubleBackPressedInterval
}
}
private fun showExitInstructions() {
Handler().postDelayed({
if(!doubleTap) {
Toast.makeText(this, "Try Agian", Toast.LENGTH_SHORT).show()
}
}, doubleBackPressedInterval)
}
答案 23 :(得分:1)
我通常会添加评论,但是我的声誉不允许这样做。 所以这是我的两分钱:
在Kotlin中,您可以使用协同程序将设置延迟为false:
private var doubleBackPressed = false
private var toast : Toast ?= null
override fun onCreate(savedInstanceState: Bundle?) {
toast = Toast.maketext(this, "Press back again to exit", Toast.LENGTH_SHORT)
}
override fun onBackPressed() {
if (doubleBackPressed) {
toast?.cancel()
super.onBackPressed()
return
}
this.doubleBackPressed = true
toast?.show()
GlobalScope.launch {
delay(2000)
doubleBackPressed = false
}
}
您将必须导入:
import kotlinx.coroutines.launch
import kotlinx.coroutines.delay
import kotlinx.coroutines.GlobalScope
答案 24 :(得分:1)
这是另一种方法......使用 CountDownTimer 方法
private boolean exit = false;
@Override
public void onBackPressed() {
if (exit) {
finish();
} else {
Toast.makeText(this, "Press back again to exit",
Toast.LENGTH_SHORT).show();
exit = true;
new CountDownTimer(3000,1000) {
@Override
public void onTick(long l) {
}
@Override
public void onFinish() {
exit = false;
}
}.start();
}
}
答案 25 :(得分:1)
在这种情况下,Snackbar是比Toast显示退出操作更好的选择。以下是使用快餐栏的方法。
@Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Snackbar.make(this.getWindow().getDecorView().findViewById(android.R.id.content), "Please click BACK again to exit", Snackbar.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
答案 26 :(得分:1)
boolean doubleBackToExitPressedOnce = false;
@Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Snackbar.make(findViewById(R.id.photo_album_parent_view), "Please click BACK again to exit", Snackbar.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
答案 27 :(得分:1)
比我认为的Zefnus稍微好一点的方法。只调用System.currentTimeMillis()一次,省略return;
:
long previousTime;
@Override
public void onBackPressed()
{
if (2000 + previousTime > (previousTime = System.currentTimeMillis()))
{
super.onBackPressed();
} else {
Toast.makeText(getBaseContext(), "Tap back button in order to exit", Toast.LENGTH_SHORT).show();
}
}
答案 28 :(得分:1)
这与已接受和最多投票的回复相同,但是使用了Snackbar而不是Toast。
boolean doubleBackToExitPressedOnce = false;
@Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Snackbar.make(content, "Please click BACK again to exit", Snackbar.LENGTH_SHORT)
.setAction("Action", null).show();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
答案 29 :(得分:1)
对于具有导航抽屉的活动,请对OnBackPressed()使用以下代码
boolean doubleBackToExitPressedOnce = false;
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
if (doubleBackToExitPressedOnce) {
if (getFragmentManager().getBackStackEntryCount() ==0) {
finishAffinity();
System.exit(0);
} else {
getFragmentManager().popBackStackImmediate();
}
return;
}
if (getFragmentManager().getBackStackEntryCount() ==0) {
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);
} else {
getFragmentManager().popBackStackImmediate();
}
}
}
答案 30 :(得分:1)
我用这个
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(this,R.string.double_back_pressed)
更改秒需要关闭,指定的毫秒数
ExitApp.now(this,R.string.double_back_pressed,5000)
答案 31 :(得分:0)
在不得不多次执行相同的事情之后,决定了时间有人构建了一个简单易用的库。那是DoubleBackPress Android library
。 README
解释了随示例提供的所有API(例如ToastDisplay + Exit Activity),但这里的步骤简要介绍了。
要开始使用,请先将dependency
添加到您的应用中:
dependencies {
implementation 'com.github.kaushikthedeveloper:double-back-press:0.0.1'
}
接下来,在DoubleBackPress
中创建一个提供所需行为的Activity
对象。
DoubleBackPress doubleBackPress = new DoubleBackPress();
doubleBackPress.setDoublePressDuration(3000); // msec
然后创建一个需要在 First Back Press 上显示的Toast
。在这里,您可以创建自己的Toast
,或使用Standard Toast
中提供的library
。通过后面的选项在这里这样做。
FirstBackPressAction firstBackPressAction = new ToastDisplay().standard(this);
doubleBackPress.setFirstBackPressAction(firstBackPressAction); // set the action
现在,定义第二次背压发生时会发生什么。在这里,我们将关闭活动。
DoubleBackPressAction doubleBackPressAction = new DoubleBackPressAction() {
@Override
public void actionCall() {
finish();
System.exit(0);
}
};
最后,使用DoubleBackPress
行为覆盖您的背压行为。
@Override
public void onBackPressed() {
doubleBackPress.onBackPressed();
}
答案 32 :(得分:0)
private static final int TIME_DELAY = 2000;
private static long back_pressed;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onBackPressed() {
if (back_pressed + TIME_DELAY > System.currentTimeMillis()) {
super.onBackPressed();
} else {
Toast.makeText(getBaseContext(), "Press once again to exit!",
Toast.LENGTH_SHORT).show();
}
back_pressed = System.currentTimeMillis();
}
答案 33 :(得分:0)
你甚至可以让它变得更简单,而且不使用汉德,只做这个=)
Long firstClick = 1L;
Long secondClick = 0L;
@Override
public void onBackPressed() {
secondClick = System.currentTimeMillis();
if ((secondClick - firstClick) / 1000 < 2) {
super.onBackPressed();
} else {
firstClick = System.currentTimeMillis();
Toast.makeText(MainActivity.this, "click BACK again to exit", Toast.LENGTH_SHORT).show();
}
}
答案 34 :(得分:0)
您还可以使用Toast的可见性,因此您不需要Handler / postDelayed ultra解决方案。
Toast doubleBackButtonToast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
doubleBackButtonToast = Toast.makeText(this, "Double tap back to exit.", Toast.LENGTH_SHORT);
}
@Override
public void onBackPressed() {
if (doubleBackButtonToast.getView().isShown()) {
super.onBackPressed();
}
doubleBackButtonToast.show();
}
答案 35 :(得分:0)
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();
}
}
答案 36 :(得分:0)
在Kotlin的背面按以退出应用程序,您可以使用:
定义一个全局变量:
private var doubleBackToExitPressedOnce = false
覆盖onBackPressed:
override fun onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed()
return
}
doubleBackToExitPressedOnce = true
Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_LONG).show()
Handler().postDelayed({
doubleBackToExitPressedOnce = false;
}, 2000)
}
答案 37 :(得分:0)
这是我的看法:
int oddeven = 0;
long backBtnPressed1;
long backBtnPressed2;
@Override
public void onBackPressed() {
oddeven++;
if(oddeven%2==0){
backBtnPressed2 = System.currentTimeMillis();
if(backBtnPressed2-backBtnPressed1<2000) {
super.onBackPressed();
return;
}
}
else if(oddeven%2==1) {
backBtnPressed1 = System.currentTimeMillis();
// Insert toast back button here
}
}
答案 38 :(得分:0)
这是使用RxJava的一种方法:
override fun onCreate(...) {
backPresses.timeInterval(TimeUnit.MILLISECONDS, Schedulers.io())
.skip(1) //Skip initial event; delay will be 0.
.onMain()
.subscribe {
if (it.time() < 7000) super.onBackPressed() //7000 is the duration of a Toast with length LENGTH_LONG.
}.addTo(compositeDisposable)
backPresses.throttleFirst(7000, TimeUnit.MILLISECONDS, Schedulers.io())
.subscribe { Toast.makeText(this, "Press back again to exit.", LENGTH_LONG).show() }
.addTo(compositeDisposable)
}
override fun onBackPressed() = backPresses.onNext(Unit)
答案 39 :(得分:0)
按下两次按钮后返回
public void click(View view){
if (isBackActivated) {
this.finish();
}
if (!isBackActivated) {
isBackActivated = true;
Toast.makeText(getApplicationContext(), "Again", Toast.LENGTH_SHORT).show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
isBackActivated = false; // setting isBackActivated after 2 second
}
}, 2000);
}
}
答案 40 :(得分:0)
吐司最佳解决方案
在Java中
final AlertDialog.Builder popDialog = new AlertDialog.Builder(getActivity());
popDialog.setTitle("Set Difficulty");
popDialog.setIcon(android.R.drawable.btn_star_big_on);
LinearLayout linearLayout = new LinearLayout(ExercisesActivity.this);
LinearLayout.LayoutParams lParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
final RatingBar rating = new RatingBar(ExercisesActivity.this);
rating.setLayoutParams(lParams);
rating.setNumStars(6);
linearLayout.addView(rating);
popDialog.setView(linearLayout);
// Button OK
popDialog.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//do things
}
});
popDialog.create();
popDialog.show();
在科特林
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();
super.onBackPressed();
}
}
答案 41 :(得分:0)
我认为这是您所需要的,我的意思是当我们要显示此敬酒时,当堆栈中只有一个活动并且用户从堆栈中的最后一个活动中按回时。 >
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()
}
在这里,如果当前活动是堆栈的 root活动(第一个活动),isTaskRoot
将返回true,否则返回false。
您可以查看官方文档here
答案 42 :(得分:0)
我试图为此创建一个utils类,因此任何活动或片段都可以简化该实现。
该代码是用Kotlin编写的,并且还具有Java互操作性。
我正在使用协程延迟并重置flag变量。但是您可以根据需要进行修改。
其他文件: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 here