Android: onBackPressed () 'i Toast ile kullanmanın Doğru Yolu


85

Kullanıcıdan çıkmak isterse tekrar geri basmasını isteyen bir kod parçası yazdım. Şu anda kodum bir ölçüde çalışıyor, ancak kötü yazılmış olduğunu biliyorum ve bunu yapmanın daha iyi bir yolu olduğunu varsayıyorum. Herhangi bir öneri yardımcı olacaktır!

Kod:

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

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

5
Değiştir this.finish()ile super.onBackPressed();.
Fred

5
bunun yerine önceki ekrana / aktiviteye dönmek için this.finish()arayınNavUtils.navigateUpFromSameTask(this);
Kra

Yanıtlar:


213

Kullanıcıya çıkmak isteyip istemediğini soran bir iletişim kutusu uyguladım ve sonra super.onBackPressed()isterse arayacaktı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();
}

Yukarıdaki örnekte, WelcomeActivity'yi etkinliğinizin adıyla değiştirmeniz gerekecektir.


bu işe yarıyor, ancak benim durumumda açılır pencere yalnızca birkaç milisaniye gösteriliyor ve kaybolduktan sonra yeni pencere gösteriliyor. Evet veya hayır'ı tıklatacak vaktim yok ve hata ayıklayacak olursam, onClick yöntemini geçmiyor. Neden?
Accollativo

4
@Accollativo, senin gibi sesler hala bir çağrı var super.onBackPressed()senin içinde onBackPressed()(onClick yönteminin içine dışındaki) tanımı?
Steve Prentice

6
Gördüğüm her uygulama "ikinci geri basma" yöntemini tercih ediyor. Yanlışlıkla geri tuşuna basan bir kullanıcı, bir iletişim kutusu gösterilirse sinirlenecektir. Tost daha az müdahaleci.
Karmic Coder

@Steve Prentice Bu parçacığı uygulamamda kullanıyorum ama ya faaliyetlerimizi desteklerken çalışan bir işlemimiz varsa - süreç hala devam ediyor. Bunu nasıl düzeltebilirim? Kullanırsam android.os.Process.killProcess(android.os.Process.myPid());ama aktiviteler arasındaki animasyon o kadar düzgün değil. Bunun yerine, saniyenin yarısı kadar siyah bir ekran yanıp sönüyor.
Stanimir Yakimov

1
@Stanimir Yakimov, arkaplan işlemlerini çalıştırmak için android hizmetlerine bakın. Bu, yaşam döngüsü yönetiminizi kolaylaştıracaktır. Hala çözemiyorsanız, yeni bir soru oluşturmanızı öneririm.
Steve Prentice

19

Geri baskı için bir sayaca ihtiyacınız yok.

Sadece gösterilen tostun referansını saklayın:

private Toast backtoast;

Sonra,

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

Bu finish(), tost hala görünür durumdayken geri basarsanız ve yalnızca geri basma uygulamadan çıkılmasına neden olursa arayacaktır .


bunun yerine önceki ekrana / aktiviteye dönmek için this.finish()arayınNavUtils.navigateUpFromSameTask(this);
Kra

Burada dikkate alınması gereken alternatif bir cevap . Henüz hangi yaklaşımı tercih edeceğime karar vermedim. Bağlantılı cevabın bazı ayrıntıları buna eklenebilir, özellikle de tostu kullanıcı çıkar çıkmaz iptal etme mantığı.
ToolmakerSteve

14

Bu çok daha basit yaklaşımı kullanıyorum ...

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 tablette garip bir şey oluyor. Birkaç kez hızlı geri dönmeniz gerekiyor. 'BackToast' yaklaşımını da
sevmiyor

Çıkmadan önce tostu iptal ederseniz Note'da daha iyi çalışır mı? Bunu
ToolmakerSteve

2

Hem sizin hem de @ Steve'in yolu, kazara çıkışları önlemenin kabul edilebilir yollarıdır.

Uygulamanıza devam etmeyi seçerseniz, backpress'in 0 olarak başlatıldığından emin olmanız ve muhtemelen Timerbir soğuma süresinden sonra tuşa basıldığında 0'a sıfırlamak için bir tür uygulamanız gerekecektir. (~ 5 saniye doğru görünüyor)


2

Ayrıca, onPauseilk geri basıştan sonra kullanıcının eve bastığı veya başka yollarla uzaklaştığı durumları önlemek için sayacı sıfırlamanız gerekebilir . Aksi takdirde bir sorun görmüyorum.


1

Uygulamanızdan Birinci Aktiviteye gitmeden Direkt İkinci Aktiviteden çıkmak istiyorsanız, bu kodu deneyin ..`

İkinci Aktivitede bu kodu koyun ..

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

Ve İlk Etkinliğiniz Bu kodu koyun .....

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

Bu en iyi yoldur, çünkü kullanıcı iki saniyeden fazla geri dönmezse, geri basılan değeri sıfırlayın.

bir global değişken beyan edin.

 private boolean backPressToExit = false;

Geçersiz Kılma onBackPressedYöntemi.

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

bir değişkeni özel boolean gibi bildirmek BackPressToExit = false
Yogesh Rathi

1) Lütfen yanıtınızı yorumda belirtmek yerine belirttiğiniz boole'yi içerecek şekilde düzenleyin. Böylece insanlar beyannamenin nerede olması gerektiğini görebilir. 2) Aslında bu, zamanın farkında olmanın alternatif bir yoludur. Lütfen bunu neden "en iyi" olarak gördüğünüzü açıklayın. Özellikle, bunun bir işleyici yaratmanın ek yükü vardır - bunu yaparak ne elde edilir?
ToolmakerSteve

0

ek olarak, aramadan önce iletişim kutusunu kapatmanız gerekir activity.super.onBackPressed(), aksi takdirde "Etkinlik sızdırıldı .." hatası alırsınız.

Sweetalerdialog kitaplığımdaki örnek:

 @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

Etkinlik belirtmek için .onBackPressed () için kullanın

@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
Lütfen orijinal koda ne eklediğinizi ve nedenini açıklayın.
ToolmakerSteve

0

Bu sorunu yeni yaşadım ve aşağıdaki yöntemi ekleyerek çözdüm:

@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

Ayrıca, özelleştirilmiş Toast kullanarak aşağıdaki yolları izleyerek onBackPressed'i de kullanabilirsiniz:

görüntü açıklamasını buraya girin

özelleştirilmiş_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

Bunu kullanın, yardımcı olabilir.

@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();
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.