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 메서드를 통과하지 못합니다. 왜?
Accollativo 2013 년

4
@Accollativo, 정의 super.onBackPressed()에 아직 호출이있는 것 같습니까 onBackPressed()(onClick 메서드 내부의 것 제외)?
Steve Prentice 2013 년

6
내가 본 모든 앱은 "두 번째 뒤로 누르기"방법을 선호합니다. 사용자가 실수로 뒤로 키를 눌렀을 때 대화 상자가 표시되면 짜증이납니다. 토스트는 덜 방해가되지 않습니다.
Karmic Coder

@Steve Prentice 내 응용 프로그램에서 해당 스 니펫을 사용하지만 활동을 지원하는 동안 프로세스가 실행중인 경우 프로세스가 여전히 실행 중입니다. 어떻게 고칠까요? 사용 android.os.Process.killProcess(android.os.Process.myPid());하지만 활동 사이의 애니메이션이 그렇게 부드럽 지 않습니다. 대신에 약 1/2 초 동안 검은 색 화면이 깜박입니다.
Stanimir Yakimov 2014

1
@Stanimir Yakimov, 백그라운드 프로세스 실행을위한 Android 서비스를 살펴보세요. 그러면 수명주기 관리가 더 쉬워집니다. 그래도 알아낼 수 없다면 새 질문을 만드는 것이 좋습니다.
Steve Prentice 2014

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

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

Samsung Note 태블릿에서 이상한 일이 발생합니다. 여러 번 빠르게 반격해야합니다. 'backToast'접근 방식도 마음에 들지 않습니다 ...
SoloPilot

종료하기 전에 토스트를 취소하면 Note에서 더 잘 작동합니까? 참조
ToolmakerSteve

2

당신의 방식과 @Steve의 방식 모두 우발적 인 종료를 방지하는 허용 가능한 방법입니다.

구현을 계속하기로 선택하는 경우 백 프레스가 0으로 초기화되었는지 확인 Timer하고 쿨 다운 기간 후에 키를 누를 때 0으로 재설정하는 일종의를 구현해야합니다 . (~ 5 초가 맞는 것 같습니다)


2

또한 onPause사용자가 처음으로 뒤로 누른 후 집을 누르거나 다른 방법으로 다른 방법으로 이동하는 경우를 방지하기 위해 카운터를 재설정해야 할 수도 있습니다 . 그렇지 않으면 문제가 발생하지 않습니다.


1

첫 번째 활동으로 이동하지 않고 직접 두 번째 활동에서 애플리케이션을 종료하려면이 코드를 시도하십시오 .`

두 번째 활동에이 코드를 넣으십시오 ..

 @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 초 이상 돌아 오지 않으면 backpressed 값을 재설정하기 때문에 이것이 가장 좋은 방법입니다.

하나의 전역 변수를 선언하십시오.

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

전용 부울 backPressToExit = 거짓으로 같은 하나 개의 변수를 선언
인 Yogesh 라티에게

1) 댓글에 언급하는 대신 언급 한 부울을 포함하도록 답변을 수정하세요. 그래서 사람들은 선언이 있어야 할 곳을 볼 수 있습니다. 2) 실제로 이것은 시간을 인식하는 다른 방법입니다. 이것이 "최고"라고 생각하는 이유를 설명하십시오. 특히 이것은 핸들러를 생성하는 오버 헤드를 가지고 있습니다. 그렇게함으로써 무엇을 얻을 수 있습니까?
ToolmakerSteve

0

또한를 호출하기 전에 대화 상자를 dissmis해야합니다 activity.super.onBackPressed(). 그렇지 않으면 "Activity has leaked .."오류가 발생합니다.

내 경우 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

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

사용자 지정된 Toast를 사용하여 다음과 같은 방법으로 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.