Android:在Toast上使用onBackPressed()的正确方法


85

我写了一段代码,将提示用户是否要退出,请他们再次按。目前,我的代码在一定程度上可以正常工作,但是我知道代码编写得很差,我认为有更好的方法可以做到。任何的意见都将会有帮助!

码:

public void onBackPressed(){
    backpress = (backpress + 1);
    Toast.makeText(getApplicationContext(), " Press Back again to Exit ", Toast.LENGTH_SHORT).show();

    if (backpress>1) {
        this.finish();
    }
}

5
替换this.finish()super.onBackPressed();
弗雷德

5
this.finish()不是打电话NavUtils.navigateUpFromSameTask(this);回到上一个屏幕/活动

Answers:


213

我将实现一个对话框,询问用户是否要退出,然后致电super.onBackPressed()

@Override
public void onBackPressed() {
    new AlertDialog.Builder(this)
        .setTitle("Really Exit?")
        .setMessage("Are you sure you want to exit?")
        .setNegativeButton(android.R.string.no, null)
        .setPositiveButton(android.R.string.yes, new OnClickListener() {

            public void onClick(DialogInterface arg0, int arg1) {
                WelcomeActivity.super.onBackPressed();
            }
        }).create().show();
}

在上面的示例中,您需要用您的活动名称替换WelcomeActivity。


这项工作有效,但在我的情况下,弹出窗口仅显示几毫秒,然后消失,然后显示新窗口。我没有时间单击“是”或“否”,并且如果我对其进行调试,则不会通过onClick方法。为什么?
Accollat​​ivo

4
@Accollat​​ivo,听起来像您super.onBackPressed()onBackPressed()定义中仍然有一个调用(除了onClick方法中的那个)?
史蒂夫·普伦蒂斯

6
我见过的每个应用程序都喜欢“第二次按下”方法。如果显示对话框,则用户不小心按了返回键会很烦。吐司不那么麻烦。
Karmic Coder 2014年

@Steve Prentice我在应用程序中使用了该代码段,但是如果我们在支持活动的同时拥有正在运行的进程,该进程仍在运行。如何解决?如果我使用,android.os.Process.killProcess(android.os.Process.myPid());但活动之间的动画不是那么平滑。取而代之的是,它闪烁黑屏约一半的时间。
斯坦尼米尔·亚基莫夫

1
@Stanimir Yakimov,研究运行后台进程的android服务。这样可以简化您的生命周期管理。如果您仍然无法解决问题,建议您提出一个新问题。
史蒂夫·普伦蒂斯

19

您不需要计数器来进行后推。

只需存储对显示的吐司的引用即可:

private Toast backtoast;

然后,

public void onBackPressed() {
    if(USER_IS_GOING_TO_EXIT) {
        if(backtoast!=null&&backtoast.getView().getWindowToken()!=null) {
            finish();
        } else {
            backtoast = Toast.makeText(this, "Press back to exit", Toast.LENGTH_SHORT);
            backtoast.show();
        }
    } else {
        //other stuff...
        super.onBackPressed();
    }
}

finish()如果您在吐司仍然可见的情况下按回车键,并且仅在按回车键会导致退出应用程序时,才调用此方法。


this.finish()不是打电话NavUtils.navigateUpFromSameTask(this);回到上一个屏幕/活动

这里考虑替代答案。我尚未决定我喜欢哪种方法。链接答案的一些细节可以添加到此答案中,尤其是用户退出后立即取消吐司的逻辑。
ToolmakerSteve

14

我使用这种简单得多的方法...

public class XYZ extends Activity {
    private long backPressedTime = 0;    // used by onBackPressed()


    @Override
    public void onBackPressed() {        // to prevent irritating accidental logouts
        long t = System.currentTimeMillis();
        if (t - backPressedTime > 2000) {    // 2 secs
            backPressedTime = t;
            Toast.makeText(this, "Press back again to logout",
                                Toast.LENGTH_SHORT).show();
        } else {    // this guy is serious
            // clean up
            super.onBackPressed();       // bye
        }
    }
}

Samsung Note平板电脑上会发生一些奇怪的事情。需要快速回击几次。它也不喜欢'backToast'方法...
SoloPilot 2014年

如果您在退出前取消烤面包,是否可以在Note上更好地工作?看到这个
ToolmakerSteve

2

您的方式和@Steve的方式都是可以防止意外退出的可接受方式。

如果选择继续执行,则需要确保将backpress初始化为0,并且可能需要执行Timer某种形式的a ,以便在冷却时间过后在按键时将其重置为0。(〜5秒似乎正确)


2

您可能还需要重置计数器,onPause以防止用户在第一次按下后按回家或通过其他某种方式离开。否则,我看不到问题。


1

如果您想从直接的第二活动中退出应用程序而不转到“第一活动”,请尝试以下代码。

在“第二个活动”中放置此代码。

 @Override
public void onBackPressed() {
    new AlertDialog.Builder(this)
            .setTitle("Really Exit?")
            .setMessage("Are you sure you want to exit?")
            .setNegativeButton(android.R.string.no, null)
            .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface arg0, int arg1) {
                    setResult(RESULT_OK, new Intent().putExtra("EXIT", true));
                    finish();
                }

            }).create().show();
}

和您的第一个活动将这段代码.....

public class FirstActivity extends AppCompatActivity {

Button next;
private final static int EXIT_CODE = 100;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    next = (Button) findViewById(R.id.next);
    next.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View view) {

            startActivityForResult(new Intent(FirstActivity.this, SecondActivity.class), EXIT_CODE);
        }
    });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == EXIT_CODE) {
        if (resultCode == RESULT_OK) {
            if (data.getBooleanExtra("EXIT", true)) {
                finish();
            }
        }
    }
}

}


1

这是最好的方法,因为如果用户退回的时间不超过两秒钟,那么请重置回压值。

声明一个全局变量。

 private boolean backPressToExit = false;

替代onBackPressed方法。

@Override
public void onBackPressed() {

    if (backPressToExit) {
        super.onBackPressed();
        return;
    }
    this.backPressToExit = true;
    Snackbar.make(findViewById(R.id.yourview), getString(R.string.exit_msg), Snackbar.LENGTH_SHORT).show();
    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            backPressToExit = false;
        }
    }, 2000);
}

声明一个像私有布尔值一样的变量backPressToExit = false
Yogesh Rathi

1)请修改您的答案以包含您提到的布尔值,而不要在评论中说出来。这样人们可以看到声明应该在哪里。2)实际上,这是一种了解时间的替代方法。请解释为什么您认为这是“最佳”。具体来说,这具有创建处理程序的开销-这样做有什么好处?
ToolmakerSteve

0

此外,您需要在调用之前进行Dissmis对话框activity.super.onBackPressed(),否则会收到“活动已泄漏..”错误。

在我的例子中,使用sweetalerdialog库的示例:

 @Override
    public void onBackPressed() {
        //super.onBackPressed();
        SweetAlertDialog progressDialog = new SweetAlertDialog(this, SweetAlertDialog.WARNING_TYPE);
        progressDialog.setCancelable(false);
        progressDialog.setTitleText("Are you sure you want to exit?");
        progressDialog.setCancelText("No");
        progressDialog.setConfirmText("Yes");
        progressDialog.setCanceledOnTouchOutside(true);
        progressDialog.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
            @Override
            public void onClick(SweetAlertDialog sweetAlertDialog) {
                sweetAlertDialog.dismiss();
                MainActivity.super.onBackPressed();
            }
        });
        progressDialog.show();
    }

0

用于.onBackPressed()以支持Activity指定

@Override
public void onBackPressed(){
    backpress = (backpress + 1);
    Toast.makeText(getApplicationContext(), " Press Back again to Exit ", Toast.LENGTH_SHORT).show();

    if (backpress>1) {
        this.finish();
    }
}

1
请说明您在原始代码中添加的内容以及原因。
ToolmakerSteve

0

我只是遇到了这个问题,并通过添加以下方法解决了它:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
             // click on 'up' button in the action bar, handle it here
             return true;

        default:
            return super.onOptionsItemSelected(item);
    }
}    

0

您还可以通过以下方式使用自定义Toast使用onBackPressed:

在此处输入图片说明

custom_toast.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/txtMessage"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:drawableStart="@drawable/ic_white_exit_small"
    android:drawableLeft="@drawable/ic_white_exit_small"
    android:drawablePadding="8dp"
    android:paddingTop="8dp"
    android:paddingBottom="8dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:gravity="center"
    android:textColor="@android:color/white"
    android:textSize="16sp"
    android:text="Press BACK again to exit.."
    android:background="@drawable/curve_edittext"/>

MainActivity.java

@Override
public void onBackPressed() {

    if (doubleBackToExitPressedOnce) {
        android.os.Process.killProcess(Process.myPid());
        System.exit(1);
        return;
    }

    this.doubleBackToExitPressedOnce = true;
    Toast toast = new Toast(Dashboard.this);
    View view = getLayoutInflater().inflate(R.layout.toast_view,null);
    toast.setView(view);
    toast.setDuration(Toast.LENGTH_SHORT);
    int margin = getResources().getDimensionPixelSize(R.dimen.toast_vertical_margin);
    toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_VERTICAL, 0, margin);
    toast.show();

    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            doubleBackToExitPressedOnce=false;
        }
    }, 2000);
}

0

使用此功能可能会有所帮助。

@Override
public void onBackPressed() {
    new AlertDialog.Builder(this)
            .setTitle("Message")
            .setMessage("Do you want to exit app?")
            .setNegativeButton("NO", null)
            .setPositiveButton("YES", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    UserLogin.super.onBackPressed();
                }
            }).create().show();
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.