Gui*_*ume 311 java android back-button
我最近在很多Android应用和游戏中都注意到了这种模式:当点击后退按钮"退出"应用程序时,Toast会出现类似于"请再次单击BACK退出"的消息.
我想知道,因为我越来越频繁地看到它是一个内置的功能,你可以以某种方式访问活动?我查看了许多类的源代码,但我似乎无法找到任何相关内容.
当然,我可以考虑几种方法来轻松实现相同的功能(最容易的是在活动中保留一个布尔值,表明用户是否已经点击过一次......)但是我想知道这里是否有东西.
编辑:正如@LAS_VEGAS所说,我并不是指传统意义上的"退出".(即终止)我的意思是"回到应用程序启动活动启动之前打开的任何东西",如果这是有意义的:)
小智 897
在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);
}
Run Code Online (Sandbox Code Playgroud)
在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)
}
Run Code Online (Sandbox Code Playgroud)
我认为这个处理程序有助于在2秒后重置变量.
Sar*_*yan 216
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();
}
Run Code Online (Sandbox Code Playgroud)
回到接受的答案批评 ; 使用flag以表明如果它是在最后压TIME_INTERVAL(比如2000年)毫秒和设置-复位是通过Handler的postDelayed()方法是进入我脑海的第一件事.但是postDelayed()当活动结束时,应该取消操作,删除Runnable.
为了删除它Runnable,它不能被声明为匿名,并且与Handleraswell 一起被声明为成员.然后可以适当地调用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);
}
Run Code Online (Sandbox Code Playgroud)
感谢@NSouth的贡献; 为了防止即使在应用程序关闭后出现toast消息,Toast也可以声明为成员 - 比如说mExitToast- 并且可以mExitToast.cancel();在super.onBackPressed();调用之前取消.
Gui*_*ume 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();
}
Run Code Online (Sandbox Code Playgroud)
它完全符合我的要求.包括恢复活动时的状态重置.
小智 26
流程图:

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;
}
Run Code Online (Sandbox Code Playgroud)
Chi*_*hod 22
所有这些答案中都有最简单的方法.
只需在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();
}
Run Code Online (Sandbox Code Playgroud)
您需要将back_pressed对象定义为long活动.
Hug*_*sos 14
我使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
简约时尚.
Meh*_*sar 13
根据正确的答案和评论中的建议,我创建了一个完全正常的演示,并在使用后删除处理程序回调.
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我希望它会有所帮助!!
Rak*_*ith 11
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);
Run Code Online (Sandbox Code Playgroud)
声明变量private boolean doubleBackToExitPressedOnce = false;
将其粘贴到您的主要活动中,这将解决您的问题
小智 10
退出应用程序时使用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();
}
Run Code Online (Sandbox Code Playgroud)
这样就可以通过双重BACK按钮在一定的延迟时间内点击退出应用程序,该延迟时间为2000毫秒.
接受的答案是最佳答案,但如果您正在使用,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);
}
Run Code Online (Sandbox Code Playgroud)
它不是内置功能.我认为这甚至不是推荐的行为.Android应用无意退出:
小智 6
最后创建一个onBackPressedMethod作为Follows:
@Override
public void onBackPressed() {
if (exitToast.getView().isShown()) {
exitToast.cancel();
finish();
} else {
exitToast.show();
}
}
Run Code Online (Sandbox Code Playgroud)这个工作正常,我已经测试过.我认为这更简单.
我知道这是一个非常古老的问题,但这是做你想做的最简单的方法。
@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();
}
}
Run Code Online (Sandbox Code Playgroud)
我知道这不是最好的方法,但它工作正常!
Zefnus使用System.currentTimeMillis()的答案是最好的答案(+1)。我这样做的方式并没有比这更好,但是仍然将其发布以增加上述想法。
如果在按下后退按钮时看不见烤面包,则显示该烤面包,而在它可见的情况下(在上Toast.LENGTH_SHORT一次已经按过一次后退),则退出。
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();
}
}
Run Code Online (Sandbox Code Playgroud)
最近,我需要在我的应用程序中实现这个后退按钮功能.原始问题的答案很有用,但我还要考虑两点:
根据答案和评论,我创建了以下代码:
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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码假定使用了支持库.如果您使用片段但不使用支持库,则需要替换getSupportFragmentManager()为getFragmentManager().
if如果从不取消后退按钮,请删除第一个.if如果你不使用片段或片段后栈,请删除第二个
此外,重要的是要注意onBackPressed自Android 2.0以来支持该方法.请查看此页面以获取详细说明.要使背压功能也适用于旧版本,请将以下方法添加到您的活动中:
@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);
}
Run Code Online (Sandbox Code Playgroud)
在java中
private Boolean exit = false;
if (exit) {
onBackPressed();
}
Run Code Online (Sandbox Code Playgroud)
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
在科特林
private var exit = false
if (exit) {
onBackPressed()
}
Run Code Online (Sandbox Code Playgroud)
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)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
213626 次 |
| 最近记录: |