2011-06-20 33 views
73

Tôi đã viết một đoạn mã sẽ cung cấp cho người dùng lời nhắc yêu cầu họ nhấn lại nếu họ muốn thoát. Tôi hiện đang có mã của tôi làm việc đến một mức độ nhưng tôi biết nó được viết kém và tôi giả sử có một cách tốt hơn để làm điều đó. Bất kỳ đề nghị sẽ là hữu ích!Android: Cách thích hợp để sử dụng onBackPressed() với Bánh mì nướng

Code:

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

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

Thay thế 'this.finish() 'với' super.onBackPressed(); '. – Fred

+4

thay vì 'this.finish()' thay vì gọi 'NavUtils.navigateUpFromSameTask (this);' để quay lại màn hình/hoạt động trước –

Trả lời

178

tôi sẽ thực hiện một hộp thoại yêu cầu người dùng nếu họ muốn thoát ra và sau đó gọi super.onBackPressed() nếu họ đã làm.

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

Trong ví dụ trên, bạn cần thay thế WelcomeActivity bằng tên hoạt động của mình.

+0

cảm ơn bạn, Phương pháp này trông được đánh bóng hơn nhiều sau đó là của tôi. Cảm kích điều đó! – Nick

+0

hoạt động, nhưng trong trường hợp của tôi, cửa sổ bật lên chỉ hiển thị trong vài phần nghìn giây và sau khi biến mất và cửa sổ mới được hiển thị. Tôi không có thời gian để bấm có hoặc không, và nếu tôi gỡ lỗi nó, nó không vượt qua cho onClick phương pháp. Tại sao? – Accollativo

+2

@Accollativo, có vẻ như bạn vẫn có lệnh gọi 'super.onBackPressed()' trong định nghĩa 'onBackPressed()' của bạn (ngoài định nghĩa bên trong phương thức onClick)? –

2

Cả hai cách của bạn và cách của @ Steve đều có thể chấp nhận được để ngăn chặn tình cờ thoát.

Nếu chọn tiếp tục triển khai, bạn cần đảm bảo đã khởi động lại thành 0 và có thể triển khai Timer của một số loại để đặt lại thành 0 khi nhấn phím, sau khoảng thời gian cooldown. (~ 5 giây có vẻ đúng)

2

Bạn cũng có thể cần phải đặt lại bộ đếm trong để ngăn chặn trường hợp khi người dùng nhấn nhà hoặc điều hướng đi bằng một số phương tiện khác sau lần quay lại đầu tiên. Nếu không, tôi không thấy vấn đề gì.

14

Bạn không cần bộ đếm ngược cho các lần nhấn.

Chỉ cần lưu trữ một tham chiếu đến bánh mì nướng được hiển thị:

private Toast backtoast;

Sau đó,

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

này sẽ gọi finish() nếu bạn bấm trở lại trong khi bánh mì nướng vẫn còn nhìn thấy được, và chỉ nếu nhấn lại sẽ dẫn đến thoát khỏi ứng dụng.

+0

thay vì 'this.finish()' thay vì gọi 'NavUtils.navigateUpFromSameTask (this);' để quay lại màn hình trước/hoạt động –

+0

Một câu trả lời thay thế để xem xét [ở đây] (http://stackoverflow.com/a/14006485/199364). Tôi chưa quyết định cách tiếp cận nào tôi thích. Một số chi tiết của câu trả lời được liên kết có thể được thêm vào câu trả lời này, đặc biệt là logic để hủy bỏ bánh mì nướng ngay khi người dùng thoát. – ToolmakerSteve

13

tôi sử dụng phương pháp đơn giản hơn nhiều này ...

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 
     } 
    } 
} 
+0

Điều gì đó lạ xảy ra trên máy tính bảng Samsung Note. Cần phải quay lại nhanh gấp nhiều lần. Nó không thích cách tiếp cận 'backToast' ... – SoloPilot

+0

Nó có hoạt động tốt hơn trên Note nếu bạn hủy bỏ bánh mì nướng trước khi thoát? Xem [this] (http://stackoverflow.com/a/14006485/199364) – ToolmakerSteve

0

Đây là cách tốt nhất, bởi vì nếu người dùng không NACK hơn hai giây sau đó thiết lập lại giá trị backpressed.

khai báo một biến toàn cục.

private boolean backPressToExit = false; 

Override onBackPressed Method.

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

khai báo một biến như private boolean backPressToExit = false –

+0

1) Vui lòng sửa câu trả lời của bạn để bao gồm boolean bạn đề cập, thay vì nói rằng trong một bình luận. Vì vậy, mọi người có thể nhìn thấy nơi tuyên bố nên được. 2) Thực tế đây là một cách thay thế để nhận thức được thời gian. Hãy giải thích lý do tại sao bạn coi đây là "tốt nhất". Cụ thể, điều này có chi phí của việc tạo ra một trình xử lý - những gì đạt được bằng cách làm như vậy? – ToolmakerSteve

0

thêm vào đó, bạn cần phải dissmis thoại trước khi gọi activity.super.onBackPressed(), nếu không bạn sẽ nhận được "Hoạt động đã bị rò rỉ .." lỗi.

Ví dụ trong trường hợp của tôi với thư viện 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(); 
    } 
1

sử dụng để.onBackPressed() để sao lưu Hoạt động chỉ định

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

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

Vui lòng giải thích những gì bạn đã thêm vào mã gốc và tại sao. – ToolmakerSteve

0

Tôi chỉ có vấn đề này và giải quyết nó bằng cách thêm các phương pháp sau đây:

@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

Bạn cũng có thể sử dụng onBackPressed bằng cách sau đây sử dụng Toast tùy chỉnh:

enter image description here

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

Nếu bạn muốn thoát khỏi ứng dụng của bạn từ Hoạt động thứ hai trực tiếp mà không đi đến Hoạt động đầu tiên sau đó thử code..` này

Trong Hoạt động thứ hai đặt này mã ..

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

Và hoạt động đầu tiên của bạn Đặt mã này .....

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

}

Các vấn đề liên quan