单击后退按钮两次以退出活动

本文翻译自:Clicking the back button twice to exit an activity

I've noticed this pattern in a lot of Android apps and games recently: when clicking the back button to "exit" the application, a Toast comes up with a message similar to "Please click BACK again to exit". 我最近在很多Android应用和游戏中都注意到了这种模式:当点击后退按钮“退出”应用程序时, Toast会出现类似于“请再次单击BACK退出”的消息。

I was wondering, as I'm seeing it more and more often, is that a built-in feature that you can somehow access in an activity? 我想知道,因为我越来越频繁地看到它是一个内置的功能,你可以以某种方式访问​​活动? I've looked at the source code of many classes but I can't seem to find anything about that. 我查看了许多类的源代码,但我似乎无法找到任何相关内容。

Of course, I can think about a few ways to achieve the same functionality quite easily (the easiest is probably to keep a boolean in the activity that indicates whether the user already clicked once...) but I was wondering if there's something already here. 当然,我可以考虑几种方法来轻松实现相同的功能(最容易的是在活动中保留一个布尔值,表明用户是否已经点击过一次......)但是我想知道这里是否有东西。

EDIT : As @LAS_VEGAS mentioned, I didn't really mean "exit" in the traditional meaning. 编辑 :正如@LAS_VEGAS所说,我并不是指传统意义上的“退出”。 (ie terminated) I meant "going back to whatever was open before the application start activity was launched", if that makes sense :) (即已终止)我的意思是“回到应用程序启动活动启动之前打开的任何内容”,如果这有意义:)


#1楼

参考:https://stackoom.com/question/ZNEj/单击后退按钮两次以退出活动


#2楼

In Java Activity: 在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);
} 

In Kotlin Activity: 在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)
    }

I Think this handler helps to reset the variable after 2 second. 我认为这个处理程序有助于在2秒后重置变量。


#3楼

Process Flow Diagram: 流程图: 再按一次退出。

Java Code: 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楼

I know this is a very old question, but this is the easiest way to do what you want. 我知道这是一个非常古老的问题,但这是做你想做的最简单的方法。

@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(); 
   }
}

I know this isn't the best method, but it works fine! 我知道这不是最好的方法,但它工作正常!


#5楼

Based upon the correct answer and suggestions in comments, I have created a demo which works absolutely fine and removes the handler callbacks after being used. 根据正确的答案和评论中的建议,我创建了一个完全正常的演示,并在使用后删除处理程序回调。

MainActivity.java 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);
        }
    }

}

I hope it will be helpful !! 我希望它会有所帮助!!


#6楼

Sudheesh B Nair 's has a nice (and accepted) answer on the question, which i think should have a better alternative such as; Sudheesh B Nair在这个问题上有一个很好的(并且被接受的)答案,我认为应该有更好的选择,例如;

What's wrong with measuring time passed and checking if TIME_INTERVAL miliseconds (say 2000) passed since the last back press. 测量时间过去并检查自上次反压后是否已经过了TIME_INTERVAL毫秒(比如2000),这有什么问题。 The following sample code uses System.currentTimeMillis(); 以下示例代码使用System.currentTimeMillis(); to store the time onBackPressed() is called; 存储时间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();
}

Back on accepted answer critique ; 回到接受的答案批评 ; Using a flag to indicate if it was pressed in last TIME_INTERVAL (say 2000) milliseconds and set - reset is via Handler 's postDelayed() method was the first thing to come in my mind. 使用一个flag来指示它是否在最后的TIME_INTERVAL (比如2000)毫秒内被按下并设置 - 重置是通过HandlerpostDelayed()方法是我想到的第一件事。 But the postDelayed() action should be cancelled when activity is closing, removing the Runnable . 但是当活动结束时,应该取消postDelayed()动作,删除Runnable

In order to remove the Runnable , it must not be declared anonymous , and be declared as member along with the Handler aswell. 为了删除Runnable ,它不能声明为匿名 ,并且与Handler一起声明为成员。 Then removeCallbacks() method of Handler can be called appropriately. 然后可以适当地调用Handler removeCallbacks()方法。

The following sample is the demonstration; 以下示例是演示;

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);
}

Thanks to @NSouth for contributing; 感谢@NSouth的贡献; In order to prevent toast message appearing even after the application is closed, Toast can be declared as a member - say mExitToast - and can be cancelled via mExitToast.cancel(); 为了防止在应用程序关闭后出现toast消息 ,可以将Toast声明为成员 - 例如mExitToast - 并可以通过mExitToast.cancel();取消mExitToast.cancel(); just before super.onBackPressed(); 就在super.onBackPressed();之前super.onBackPressed(); call. 呼叫。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值