라떼는말이야

[Android] 뒤로 가기 두번 눌러 종료 구현 본문

안드로이드

[Android] 뒤로 가기 두번 눌러 종료 구현

MangBaam 2021. 5. 28. 03:44
반응형

앱을 사용하다 보면 어떤 작업을 하다가 뒤로 가기 버튼을 잘못 눌러서 작업 중이던 내역이 전부 날아가는 불상사가 발생하는 경우를 한번쯤 겪어 봤을 것이다.

그래서 많은 경우에 뒤로 가기 버튼을 두번 연속 눌러야만 종료되도록 만들어놓은 것을 볼 수 있다.

본 게시글에서는 이처럼 뒤로 가기 버튼을 두번 연속 눌러야지 종료되도록 하는 예제와 상황을 소개한다.

 

재활용성을 높이기 위해서 MainActivity에서 직접 구현하는 것이 아닌 별도의 클래스로 작성하는 예제를 소개한다.

간단히 MainActivity에서 구현하고 싶다면 필요한 부분만 가져다 써도 무방하다.


1. 자바 클래스 생성 (BackKeyHandler <- 원하는 이름으로)

 

Java 클래스 생성

2. 생성자 작성

Alt + Insert 를 눌러 Constructor를 선택하여 생성자를 생성한다.

 

3. 생성자의 매개 변수로 Activity를 받는다.

생성자 작성

private Activity activity로 변수를 선언하고, 생성자로 받은 Activity를 this.activity에 저장한다.

activity를 받는 것은 뒤로 가기 버튼이 동작 할 activity에 클래스를 동작시키기 위함이다.

 

 

 

 

 

4. showGuide() 메소드 정의

showGuide() 메소드는 사용자가 뒤로 가기 버튼을 눌렀을 때 Toast를 띄워줄 것인데, Toast에 들어갈 내용을 정의하는 메소드이다.

 

전역 변수로 Toast toast;를 선언하고, showGuide() 메소드 내부에서 toast에 Toast를 생성한다.

 

showGuide()와 showGuide(String msg) 이렇게 같은 이름의 메소드 두 개를 작성했는데 이렇게 메소드 이름이 동일하지만 매개 변수의 개수가 다르거나 매개 변수의 타입이 다른 경우를 오버로딩이라고 하며 상황에 따른 다양한 동작을 위해 존재하는 기능이다.

 

이 경우 매개 변수 없는 showGuide()를 실행하면 개발자가 직접 입력해놓은 '뒤로' 버튼을 한번 더 누르시면 종료됩니다 라는 문구가 Toast로 띄워지며

매개 변수로 msg를 받은 showGuide()를 실행하면 msg가 Toast로 띄워진다.

 

5. onBackPressed() 메소드 작성

onBackPressed() 메소드 작성

8번 라인에 backKeyPressedTime 이라는 long형 변수를 선언하고 0으로 초기화한다.

이 변수는 뒤로 가기 버튼을 누른 시간을 저장하기 위한 변수이다.

 

그리고 onBackPressed() 메소드를 위와 같이 작성한다.

backKeyPressedTime + 2000 으로 되어있는 부분은 2000밀리초 즉 2초를 뜻하고

 

System.currentTimeMillis()는 1970년 1월 1일 00:00:00.000 이후로 현재까지의 시간을 밀리초로 표현하는 굉장히 큰 수가 나온다.

backKeyPressedTime의 초기값이 0이므로 당연히 첫 번째 if문이 실행된다.

if 문 안에서 backKeyPressedTime 변수에 현재 시간을 넣었고, showGuide() 메소드를 호출하여 Toast를 띄운다.

 

즉 한 번 뒤로 가기 버튼을 눌러도 종료되지 않고 Toast만 띄우게 된다.

 

이후 한번 더 뒤로 가기 버튼을 눌렀을 때 최초로 뒤로 가기 버튼을 누른 뒤 2초가 넘었으면 첫 번째 if문이 실행되어서 또 다시 종료되지 않고 Toast만 띄울 것이며

 

2초가 지나지 않은 상황에서 또 다시 뒤로 가기 버튼을 눌렀다면 두 번째 if문이 실행되면서 액티비티를 종료시키고 Toast가 뜨지 않도록 한다.

 

 

 

 

 

확장

6. 다양한 onBackPressed() 메소드 오버로딩

	/* 첫 번째 */
    public void onBackPressed() {
        if (System.currentTimeMillis() > backKeyPressedTime + 2000) {
            backKeyPressedTime = System.currentTimeMillis();
            showGuide();
            return;
        }

        if (System.currentTimeMillis() <= backKeyPressedTime + 2000) {
            activity.finish();
            toast.cancel();
        }
    }
	/* 두 번째 */
    public void onBackPressed(String msg) {
        if (System.currentTimeMillis() > backKeyPressedTime + 2000) {
            backKeyPressedTime = System.currentTimeMillis();
            showGuide(msg);
            return;
        }

        if (System.currentTimeMillis() <= backKeyPressedTime + 2000) {
            activity.finish();
            toast.cancel();
        }
    }
	/* 세 번째 */
    public void onBackPressed(double time) {
        if (System.currentTimeMillis() > backKeyPressedTime + (time * 1000)) {
            backKeyPressedTime = System.currentTimeMillis();
            showGuide();
            return;
        }

        if (System.currentTimeMillis() <= backKeyPressedTime + 2000) {
            activity.finish();
            toast.cancel();
        }
    }
	/* 네 번째 */
    public void onBackPressed(String msg, double time) {
        if (System.currentTimeMillis() > backKeyPressedTime + (time * 1000)) {
            backKeyPressedTime = System.currentTimeMillis();
            showGuide(msg);
            return;
        }

        if (System.currentTimeMillis() <= backKeyPressedTime + 2000) {
            activity.finish();
            toast.cancel();
        }
    }

첫 번째

위에서 작성한 것과 동일한 메소드이다.

 

두 번째

매개 변수로 문자열을 받아서 그 문자열을 Toast로 띄운다.

Toast 메시지를 커스텀 하고 싶을 때 사용한다.

 

세 번째

매개 변수로 double형 숫자를 받는다.

이 숫자는 뒤로 가기 버튼을 두 번 누르는 시간 간격을 의미한다. 단위는 초(s)이다.

onBackPressed(3)으로 호출하면 시간 간격을 3초로 설정한다.

 

네 번째

매개 변수로 문자열과 double형 숫자를 받는다.

두 번째와 세 번째 기능을 합친 메소드이다.

즉, Toast로 띄울 문자열과 시간 간격을 커스텀 할 수 있다.

 

 

 

 

 

클래스 사용

1. 위에서 작성한 BackKeyHandler 클래스를 사용하고자 하는 액티비티로 이동한다. (이 예제에서는 MainActivity)

2. BackKeyHandler 클래스의 인스턴스를 생성한다.

MainActivity

BackKeyHandler 클래스는 생성자에서 매개 변수로 액티비티를 받기 때문에 매개 변수로 자기 자신인 this를 넣어준다.

 

3. onBackPressed 메소드 재정의

Override onBackPressed()

ctrl + o를 누르면 Override를 할 수 있다.

위 창이 뜨면 onBackPressed라고 검색하고 onBackPressed():void라고 적혀있는 것을 선택하고 하단에 OK 버튼을 눌러주면 자동으로 입력된다.

자동으로 입력된 super.onBackPressed()는 기존의 뒤로 가기 버튼을 눌렀을 때 동작하는 부분이다. 즉 뒤로 가기 버튼을 한 번 누르면 액티비티가 종료되는 기능이다.

우리는 이 기능을 BackKeyHandler 클래스에서 재정의 했기 때문에 super.onBackPressed()는 지워주고 다음과 같이 작성한다.

 

저렇게 매개 변수 없이 호출하면 2초의 간격으로 설정되고, Toast 메시지는 '뒤로' 버튼을 두 번 누르면 종료됩니다. 라고 설정된다.

backKeyHandler.onBackPressed();
backKeyHandler.onBackPressed("\'뒤로\' 버튼을 두 번 누르면 종료됩니다.\n입력한 내용이 지워집니다.");
backKeyHandler.onBackPressed(5);
backKeyHandler.onBackPressed("5초 내로 한번 더 누르세요", 5);

위와 같이 다양한 형태로 커스텀해서 사용 가능하다. (4개의 형태 중 하나 선택해서 사용)

 

 

 

 

 

BackKeyHandler.java 전체 소스코드

package com.example.???;

import android.app.Activity;
import android.widget.Toast;

public class BackKeyHandler {

    private long backKeyPressedTime = 0;
    private Activity activity;
    private Toast toast;

    public BackKeyHandler(Activity activity) {
        this.activity = activity;
    }

    public void onBackPressed() {
        if (System.currentTimeMillis() > backKeyPressedTime + 2000) {
            backKeyPressedTime = System.currentTimeMillis();
            showGuide();
            return;
        }

        if (System.currentTimeMillis() <= backKeyPressedTime + 2000) {
            activity.finish();
            toast.cancel();
        }
    }

    public void onBackPressed(String msg) {
        if (System.currentTimeMillis() > backKeyPressedTime + 2000) {
            backKeyPressedTime = System.currentTimeMillis();
            showGuide(msg);
            return;
        }

        if (System.currentTimeMillis() <= backKeyPressedTime + 2000) {
            activity.finish();
            toast.cancel();
        }
    }

    public void onBackPressed(double time) {
        if (System.currentTimeMillis() > backKeyPressedTime + (time * 1000)) {
            backKeyPressedTime = System.currentTimeMillis();
            showGuide();
            return;
        }

        if (System.currentTimeMillis() <= backKeyPressedTime + 2000) {
            activity.finish();
            toast.cancel();
        }
    }

    public void onBackPressed(String msg, double time) {
        if (System.currentTimeMillis() > backKeyPressedTime + (time * 1000)) {
            backKeyPressedTime = System.currentTimeMillis();
            showGuide(msg);
            return;
        }

        if (System.currentTimeMillis() <= backKeyPressedTime + 2000) {
            activity.finish();
            toast.cancel();
        }
    }

    private void showGuide() {
        toast = Toast.makeText(activity, "\'뒤로\' 버튼을 한번 더 누르시면 종료됩니다", Toast.LENGTH_SHORT);
        toast.show();
    }

    private void showGuide(String msg) {
        toast = Toast.makeText(activity, msg, Toast.LENGTH_SHORT);
        toast.show();
    }
}

MainActivity 전체 소스코드

package com.example.???;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private BackKeyHandler backKeyHandler = new BackKeyHandler(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public void onBackPressed() {
        /* 다음 4가지 형태 중 하나 선택해서 사용 */
        
        //backKeyHandler.onBackPressed();
        //backKeyHandler.onBackPressed("\'뒤로\' 버튼을 두 번 누르면 종료됩니다.\n입력한 내용이 지워집니다.");
        //backKeyHandler.onBackPressed(5);
        backKeyHandler.onBackPressed("5초 내로 한번 더 누르세요", 5);
    }
}

 

 

 

 

반응형
Comments