안녕하세요! 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
공감은 로그인이 필요없습니다.
공감은 저에게 포스팅을 이어나갈 수 있는 힘이 됩니다.