- fragment 에서 onBackPressed() 접근하기2022년 08월 13일 22시 50분 28초에 업로드 된 글입니다.작성자: 핀수728x90반응형
onBackPressed()
Called when the activity has detected the user's press of the back key.
말그대로 사용자가 뒤로 가기 버튼을 클릭 했을 때 해당 메서드가 호출된다.
@Override public void onBackPressed() { super.onBackPressed(); }
ComponentActivity가 들고 있는 메서드이고
AppCompatActivity 는 FragmentActivity를 상속 받고
FragmentActivity는 ComponentActivity를 상속 받는다.
따라서 onBackPressed 메서드는 activty에서는 얼마든지
오버라이딩해서 입맛대로 사용이 가능하다.
출처 : 마이케이티 앱 메인화면에서 뒤로 가기 버튼을 눌렀을 때,
앱을 종료하겠냐는 다이얼로그를 띄운다고 생각해보자
MainActivity.java@Override public void onBackPressed() { AlertDialog.Builder builder = new AlertDialog.Builder(mContext); builder.setMessage("앱을 종료하시겠습니까?") .setPositiveButton("앱 종료", (dialogInterface, i) -> finish()) .setNegativeButton("취소", (dialogInterface, i) -> dialogInterface.dismiss()) .create() .show(); }
만약 Single Activity Architecture (SAA) 구조라면?*SAA : 하나 혹은 적은 갯수의 activity만을 사용하고 나머지 화면은 fragment로 구성한 구조. 주로 Jetpack Navigation과 함께 사용된다.
Fragment에서 해당 작업이 이루어져야 할 것이다.
그러나 프래그먼트에서는 onBackPressed를 오버라이딩 할 수 없다.
그래서 처음에는 현재 프래그먼트를 알아내 해당 프래그먼트의 타입을 알아내 필요한 행위를 지정했다.
MainFragment.java@Override public void onBackPressed() { Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.nav_host).getChildFragmentManager().getFragments().get(0); if (currentFragment instanceof MainFragment){ AlertDialog.Builder builder = new AlertDialog.Builder(mContext); builder.setMessage("앱을 종료하시겠습니까?") .setPositiveButton("앱 종료", (dialogInterface, i) -> finish()) .setNegativeButton("취소", (dialogInterface, i) -> dialogInterface.dismiss()) .create() .show(); } else { super.onBackPressed(); } }
OnBackPressedCallback
뒤로 가기 버튼 이벤트가 발생했을 때 처리해야하는 것들이 많아짐에 따라,
처리 해야줘야 할 fragment들이 많아짐에 따라
위의 방법은 부담스러웠다.
fragment내에서 처리하지 못하고 MainActivity까지 끌고 나와야했기 때문이다.
(fragment 내부의 요소에 접근해야할 때)
MainFragment.java@Override public void onAttach(@NonNull Context context) { super.onAttach(context); requireActivity().getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback); } private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { AlertDialog.Builder builder = new AlertDialog.Builder(mContext); builder.setMessage("앱을 종료하시겠습니까?") .setPositiveButton("앱 종료", (dialogInterface, i) -> requireActivity().finish()) .setNegativeButton("취소", (dialogInterface, i) -> dialogInterface.dismiss()) .create() .show(); } };
OnBackPressedDispatcher
- 뒤로 가기 버튼 이벤트가 하나 이상의 OnBackPressedCallback 객체로 전달되는 방법을 제어
OnBackPressedCallback
- 해당 객체의 생성자는 초기 사용 설정 상태를 나타내며 콜백이 사용 설정됐다면 true 를 반환,
디스패처가 handleOnBackPressed()를 호출해 해당 이벤트를 처리한다.
addCallback(LifecycleOwner owner, OnBackPressedCallback onBackPressedCallback)
- LifecycleOwner가 동작할 때만 해당 콜백이 추가되도록 설정
- 해당 메서드를 통해 여러개의 콜백을 제공할 수 있다.
- 콜백은 추가된 역순으로 호출된다. (A - B - C 순 -> C - B - A 순으로 호출될 것)
- 책임 연쇄 패턴 (Chain of Responsibility) 을 따른다고 한다.
-> 라이프사이클이 시작될 때 (Lifecycle.State.STARTED), 해당 상태에 진입할 때까지 chain에 추가되지 않는다.
- 콜백을 제거하려는 경우 remove()를 호출해야한다.
그러나 콜백은 연결된 LifecycleOwner가 제거될 때 자동으로 삭제 되기 때문에 필수는 아니다.
References
아래 글을 참고하여 작성 되었습니다.
https://heegs.tistory.com/128
https://developer.android.com/guide/navigation/navigation-custom-back?hl=ko728x90반응형'pinslog > Log.daily()' 카테고리의 다른 글
다음글이 없습니다.이전글이 없습니다.댓글