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);する代わりに
Kraへ

回答:


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 2013年

4
@Accollat​​ivo、あなたのような音はまだへの呼び出し持ってsuper.onBackPressed()あなたの中onBackPressed()(のonClickメソッド内以外の)定義は?
スティーブプレンティス2013年

6
私が見たすべてのアプリは、「セカンドバックプレス」方式を支持しています。ダイアログが表示された場合、ユーザーが誤って戻るキーを押すとイライラします。トーストは邪魔になりません。
Karmic Coder

@Steve Prenticeアプリケーションでそのスニペットを使用していますが、アクティビティをバックアップしているときに実行中のプロセスがある場合はどうでしょうか。プロセスはまだ実行中です。それを修正する方法は?使用してandroid.os.Process.killProcess(android.os.Process.myPid());も、アクティビティ間のアニメーションはそれほどスムーズではありません。これの代わりに、それは約半分の秒の間黒い画面を点滅させています。
スタニミールヤキモフ2014

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);する代わりに
Kraへ

ここで検討する別の答え。どちらのアプローチを好むかはまだ決めていません。リンクされた回答の詳細、特にユーザーが終了するとすぐにトーストをキャンセルするロジックをこれに追加できます。
toolmakerSteve 2016

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

SamsungNoteタブレットで何か奇妙なことが起こります。数倍速く反撃する必要があります。それは...どちらかの「backToast」アプローチ好きではない
SoloPilot

終了する前にトーストをキャンセルすると、Noteでうまく機能しますか?これを
ToolmakerSteve 2016

2

あなたの方法と@Steveの方法の両方が、偶発的な終了を防ぐための許容可能な方法です。

実装を続行することを選択した場合は、Timerバックプレスを0に初期化する必要があります。また、クールダウン期間の後、キーを押すと0にリセットするための何らかの実装が必要になります。(〜5秒は正しいようです)


2

またonPause、ユーザーが最初に押した後にホームを押したり、他の方法で移動したりする場合を防ぐために、カウンターをリセットする必要がある場合もあります。それ以外の場合、問題は発生しません。


1

最初のアクティビティに移動せずに直接の2番目のアクティビティからアプリケーションを終了する場合は、このコードを試してください。

2番目のアクティビティにこのコードを入れます。

 @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

これが最善の方法です。ユーザーが2秒以内に戻っていない場合は、押し戻された値をリセットするためです。

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

1つの変数をprivateboolean backPressToExit = falseのように宣言します
Yogesh Rathi 2015

1)コメントで言うのではなく、言及したブール値を含めるように回答を編集してください。したがって、人々は宣言がどこにあるべきかを知ることができます。2)確かに、これは時間を意識するための代替方法です。これを「最良」と考える理由を説明してください。具体的には、これにはハンドラーを作成するオーバーヘッドがあります-そうすることで何が得られますか?
toolmakerSteve 2016

0

さらに、を呼び出す前にダイアログを表示する必要があり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()を使用してアクティビティを指定します

@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 2016

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

カスタマイズされたトーストを使用して次の方法でonBackPressedを使用することもできます。

ここに画像の説明を入力してください

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

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();
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.