2010-03-17 35 views
29

Tôi có một hoạt động có chứa một số mục có thể chỉnh sửa của người dùng (trường EditText, RatingBar, v.v.). Tôi muốn nhắc người dùng nếu nút quay lại/trang chủ được nhấn và các thay đổi đã được thực hiện mà chưa được lưu. Sau khi đọc qua tài liệu android, có vẻ như đoạn mã này nên đi theo phương thức onPause. Tôi đã thử đặt một AlertDialog trong onPause Tuy nhiên hộp thoại được hiển thị và sau đó ngay lập tức rơi xuống vì không có gì là có để ngăn chặn tạm dừng hoàn thành.Android: Nhắc người dùng lưu thay đổi khi nút Quay lại được nhấn

Đây là những gì tôi đã đưa ra cho đến nay:

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

Tôi có đi đúng hướng hay là có một cách khác để đạt được những gì tôi đang cố gắng để làm ở đây? Bất kỳ sự trợ giúp nào đều sẽ là tuyệt vời!

Trả lời

95

Bạn không hoàn toàn đi đúng hướng; những gì bạn nên làm là trọng onKeyDown() và nghe cho phím trở lại, sau đó trọng hành vi mặc định:

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

Nếu bạn chỉ hỗ trợ Android 2.0 và cao hơn, họ đã thêm một onBackPressed() bạn có thể sử dụng thay vì:

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

Câu trả lời này về cơ bản bị tách rời khỏi this blog post. Đọc nó nếu bạn cần dài ép, tương thích hỗ trợ, hỗ trợ cho ảo phím cứng, hoặc liệu các giải pháp như onPreIme(), vv

+0

Sử dụng phương pháp onKeyDown() sẽ có những vấn đề tương tự như onPause(). Nếu tôi cố gắng hiển thị một hộp thoại cảnh báo trong khối onKeyDown khi tôi phát hiện mã khóa Back, hộp thoại vẫn không chặn. Tôi sẽ thấy cảnh báo trong giây lát cho đến khi super.onKeyDown được nhấn sẽ làm cửa sổ đóng lại. Có cách nào để buộc một phản ứng với AlertDialog trước khi tiếp tục? – chriskopec

+0

Bạn có đang gọi super.onKeyDown() nếu bạn sử dụng nút quay lại không? Tôi giả sử rằng bạn chỉ nên sử dụng "trả về true" nếu bạn mở hộp thoại, để chỉ ra cho hệ thống mà bạn đã tiêu thụ nút quay lại; nếu không, bằng cách gọi super(), bạn sẽ vẫn kết thúc cuộc gọi tất cả những thứ kết thúc hoạt động. –

+0

Đó là nó, Cảm ơn! – chriskopec

10

Bạn nghĩ gì về phương pháp này ..

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

} 
0

Tôi đang làm điều tương tự mà bạn làm. Tôi có một hoạt động với thông tin khách hàng (EditText cho tên, họ, email, ..., bạn biết đấy, EditText ở khắp mọi nơi) và tôi đã sử dụng AsyncTask cho điều đó và nó hoạt động tuyệt vời.

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

} 
2

Dưới đây là một số mẫu mã:

@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(); 
    } 
} 
Các vấn đề liên quan