安卓:当用户按下返回按钮时提示保存更改

35

我有一个活动包含多个可供用户编辑的项目(EditText字段,RatingBar等)。 如果按下返回/主页按钮并且已经进行了尚未保存的更改,则希望提示用户。 通过阅读Android文档,似乎这段代码应该放在onPause方法中。 我已经尝试在onPause中放置AlertDialog,但是对话框会显示然后立即关闭,因为没有任何内容来阻止暂停完成。

到目前为止,这就是我的想法:

@Override
protected void onPause() {
    super.onPause();

    AlertDialog ad = new AlertDialog.Builder(this).setMessage(
            R.string.rating_exit_message).setTitle(
            R.string.rating_exit_title).setCancelable(false)
            .setPositiveButton(android.R.string.ok,
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog,
                                int whichButton) {
                            // User selects OK, save changes to db
                        }
                    }).setNeutralButton(android.R.string.cancel,
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog,
                                int whichButton) {
                            // User selects Cancel, discard all changes
                        }
                    }).show();
}

我是否在正确的方向上,或者有其他方法可以完成我在这里尝试做的事情?任何帮助都将不胜感激!

4个回答

96

你的思路有一点偏差;你应该重写onKeyDown()方法并监听返回键,然后重写默认行为:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
    if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
        // do something on back.
        return true;
    }

    return super.onKeyDown(keyCode, event);
}

如果你只支持Android 2.0及以上版本,则可以使用添加了onBackPressed()的方法:

@Override
public void onBackPressed() {
    // do something on back.
    return;
}

这个答案基本上是从这篇博客文章中获取而来的。如果您需要长按、兼容性支持、虚拟硬键支持或像onPreIme()这样的原始解决方案,请阅读该文章。


使用onKeyDown()方法会遇到与onPause()相同的问题。如果我在检测到Back keycode时尝试在onKeyDown块中显示警报对话框,该对话框仍然不会阻止。我会看到警报短暂地出现,直到按下super.onKeyDown,这将导致窗口关闭。有没有一种方法可以在继续之前强制响应AlertDialog? - chriskopec
如果你消耗了返回按钮,你是否在调用 super.onKeyDown()?我认为,如果你弹出对话框,应该只使用 "return true" 来指示系统你已经消费了返回按钮的按下;否则,通过调用 super(),你仍然会结束所有完成活动的事情。 - Dan Lew

11

你认为这种方法怎么样?..

private  void exit(){
    this.finish();
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {

        AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
        alertbox.setTitle("Message");
        alertbox.setMessage("Quit ??? ");

        alertbox.setPositiveButton("Yes",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface arg0, int arg1) {
                        exit();
                    }
                });

        alertbox.setNeutralButton("No",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface arg0, int arg1) {
                    }
                });

        alertbox.show();

        return true;
    } else {
        return super.onKeyDown(keyCode, event);
    }

}

4

以下是一些示例代码:

@Override
public void onBackPressed() {       
    if (isDirty) {          
        new AlertDialog.Builder(this)
            .setTitle("You have made some changes.")
            .setMessage("Would you like to save before exiting?")
            //.setNegativeButton(android.R.string.no, null)            
            .setNegativeButton("No", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface arg0, int arg1) {
                    MyActivity.super.onBackPressed();
                }
            })            
            .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface arg0, int arg1) {                    
                    if (Save())
                        MyActivity.super.onBackPressed();
                }
            }).create().show();
    }
    else {
        MyActivity.super.onBackPressed();
    }
}

什么是isdirty? - Marian Paździoch

0

我正在做你所做的事情。我有一个包含客户信息的活动(姓名、姓氏、电子邮件等的EditText,你知道,在各个地方都有EditText),我使用了AsyncTask来完成这个任务,它运行得非常好。

    @Override
public void onBackPressed() 
{
            // start async task for save changes.
    new GuardandoContactoHilo().execute()
}

public void VolverAtras()
{
    super.onBackPressed();
}

public class GuardandoContactoHilo extends AsyncTask< Void, Void, Void> 
{

     private ProgressDialog saving;


    @Override
    protected void onPreExecute()
    {
        super.onPreExecute();
        saving = new ProgressDialog(cont);

        saving.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        saving.setMessage("Saving customer ...");
        saving.show();
    }

    @Override
    protected void onPostExecute(Void result) 
    {
        super.onPostExecute(result);
        saving.dismiss();
        VolverAtras(); // go back !!
    }

    @Override
    synchronized protected Void doInBackground(Void... arg0) 
    {

        // do what you want to do before come back ! for example, save data ;)
        return null;
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接