본문 바로가기

프로그래밍 [KOR]/Android

Fragment 에서 뒤로가기 버튼 입력 처리


안녕하세요! Ji-nun입니다!


주제 : Fragment 에서 뒤로가기 버튼 입력 처리


원래 Fragment 상에서 뒤로가기 버튼을 눌렀을 때는 그 입력이 Fragment 를 품고있는 Activity 가 처리합니다.


하지만 Fragment 에서 뒤로가기 버튼을 눌렀을때의 동작을 Activity 와 다르게 처리하고 싶을 때가 있습니다.


메인(중심) Fragment 에선 뒤로가기 버튼을 두번 눌렀을 때는 앱이 종료될 수 있도록 하고


다른 Fragment 에선 뒤로가기 버튼을 눌렀을 때 메인 Fragment 로 가게끔 말이죠.


Stack 을 사용해도 되나, 전 어떤 Fragment 든지 메인으로 가게끔하는 방법을 소개해드리려 합니다.



1. MainActivity 에 Listener 생성



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    // 뒤로가기 버튼 입력시간이 담길 long 객체
    private long pressedTime = 0;
 
    // 리스너 생성
    public interface OnBackPressedListener {
        public void onBack();
    }
 
    // 리스너 객체 생성
    private OnBackPressedListener mBackListener;
 
    // 리스너 설정 메소드
    public void setOnBackPressedListener(OnBackPressedListener listener) {
        mBackListener = listener;
    }
 
    // 뒤로가기 버튼을 눌렀을 때의 오버라이드 메소드
    @Override
    public void onBackPressed() {
 
        // 다른 Fragment 에서 리스너를 설정했을 때 처리됩니다.
        if(mBackListener != null) {
            mBackListener.onBack();
            Log.e("!!!""Listener is not null");
        // 리스너가 설정되지 않은 상태(예를들어 메인Fragment)라면
        // 뒤로가기 버튼을 연속적으로 두번 눌렀을 때 앱이 종료됩니다.
        } else {
            Log.e("!!!""Listener is null");
            if ( pressedTime == 0 ) {
                Snackbar.make(findViewById(R.id.main_layout),
                     " 한 번 더 누르면 종료됩니다." , Snackbar.LENGTH_LONG).show();
                pressedTime = System.currentTimeMillis();
            }
            else {
                int seconds = (int) (System.currentTimeMillis() - pressedTime);
 
                if ( seconds > 2000 ) {
                    Snackbar.make(findViewById(R.id.main_layout), 
                        " 한 번 더 누르면 종료됩니다." , Snackbar.LENGTH_LONG).show();
                    pressedTime = 0 ;
                }
                else {
                    super.onBackPressed();
                    Log.e("!!!""onBackPressed : finish, killProcess");
                    finish();
                    android.os.Process.killProcess(android.os.Process.myPid());
                }
            }
        }
    }
cs



2. Fragment 에 리스너 생성 및 등록



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class OtherFragment extends Fragment implements MainActivity.OnBackPressedListener{
    MainFragment mainFragment;
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_help, container, false);
 
        mainFragment = new MainFragment();
 
        return view;
    }
 
    @Override
    public void onBack() {
        Log.e("Other""onBack()");
        // 리스너를 설정하기 위해 Activity 를 받아옵니다.
        MainActivity activity = (MainActivity)getActivity();
        // 한번 뒤로가기 버튼을 눌렀다면 Listener 를 null 로 해제해줍니다.
        activity.setOnBackPressedListener(null);
        // MainFragment 로 교체
        getActivity().getFragmentManager().beginTransaction()
                .replace(R.id.fragment_container, mainFragment).commit();
        // Activity 에서도 뭔가 처리하고 싶은 내용이 있다면 하단 문장처럼 호출해주면 됩니다.
        // activity.onBackPressed();
    }
 
    // Fragment 호출 시 반드시 호출되는 오버라이드 메소드입니다.
    @Override
    //                     혹시 Context 로 안되시는분은 Activity 로 바꿔보시기 바랍니다.
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.e("Other""onAttach()");
        ((MainActivity)context).setOnBackPressedListener(this);
    }
}
cs



코드 내부에 주석으로 설명을 달았습니다.


이해가 안되는 부분이 있으시거나 에러가 나신다면 댓글 또는 하단의 이메일로 연락 부탁드립니다.


감사합니다.




제 나름대로 생각을 정리하며 포스팅합니다.

정보전달에 있어 차질이 생기는 것을 우려해 나름대로 확실하게 검증을 하고 포스팅하려고 노력합니다.

본 포스팅에 잘못된 정보가 있거나 수정해야할 내용이 있다면 댓글 또는 아래의 이메일로 알려주시면 감사하겠습니다.

E-mail : silent_lhr@naver.com



공감은 로그인이 필요없습니다.

공감은 저에게 포스팅을 이어나갈 수 있는 힘이 됩니다.