Fragment 간 이동 할 때 add, replace, remove, addToBackStack 등
다양한 방법으로 Fragment 를 다룰 수 있다.
내가 겪은 이슈는 A -> B 로 Fragment 를 이동할 시
replace 를 이용하면 기존 stack 에 쌓인 Fragment(A) 는 사라지고,
replace 로 대체되는 Fragment(B) 만 남아 있어야 한다.
하지만,
그렇지 않았다.
그래서
Fragment(A) 에 있는 버튼 리스너 들이 Fragment(B) View 에서 눌리게 된다...
일단 나는 아래와 같이 코드를 작성해서, 범용적으로 Fragment 를 사용하려고 했다.
replace, add, remove, popBackStack
fun Activity?.moveFragment(fragment: Fragment) {
this.isNotNull {
(it as 액티비티명).supportFragmentManager.beginTransaction().replace(R.id.레이아웃명, fragment).commit()
}
}
fun Activity?.popBackStack() {
this.isNotNull {
val fm = (it as 액티비티명).supportFragmentManager
if (fm.backStackEntryCount > 0) {
fm.popBackStack()
}
}
}
fun Activity?.removeFragment(fragment: Fragment) {
this.isNotNull {
(it as 액티비티명).supportFragmentManager.beginTransaction().remove(fragment).commit()
}
}
fun Activity?.addFragment(fragment: Fragment) {
this.isNotNull {
(it as 액티비티명).supportFragmentManager.beginTransaction().add(R.id.레이아웃명, fragment).addToBackStack("").commit()
}
}
이슈가 난 상황은 add 를 사용했다면 충분히 그럴 수 있다고 생각하는데?
그런데 replace 가 이러하니, 너무나 궁금해서 라이프사이클이 어떻게 동작하는지 로그를 한 번 찍어보았다.
이슈 상황
Fragment A -> Fragment B
Fragment B -> Fragment A
정상적인 상황
Fragment A -> Fragment B
Fragment B > Fragment A
A => MoreFragment
B => CouponTermsFragment
위 사진을 보면, Fragment A 가 사라지지 않은 것을 알 수 있다.
이것만 보면 Fragment B 에서 A의 버튼 리스너가 동작하는지는 알 수 있는데
이러면 안되는 거 아닌가?
replace 는 이전에 쌓인 Fragment 는 다 사라지게 아닌가? 왜 이렇게 되지?
웃긴건, 처음으로 A -> B 로 이동하면 이슈 상황처럼 라이프사이클이 움직여지고
두 번째부턴 정상적인 상황 처럼 라이프사이클이 움직여진다.
이건, add 와 replace 둘 다 똑같은 현상이였다.
이유가 뭘까?
솔직히 정확한 이유를 찾지 못했다. 다만, 아래 글을 읽으면 조금 도움될 것이다.
https://stackoverflow.com/questions/11326155/fragment-onresume-onpause-is-not-called-on-backstack
그렇지만 어떻게 해야할 지를 해결은 해야했으니 아래은 방법으로 해결했다.
어떻게 해야할까?
일단, 라이프사이클을 확인해보면, 생각했던대로 replace 가 되지 않는 걸 확인할 수 있다.
따라서 Fragment(A) > Fragment(B) 로 이동할 시, add + addToBackStack 를 사용하였다.
addToBackStack 을 이용해서 기존 Host Activity Stack 에 Fragment 를 넣어서 BaskStack 했을 시, 이전 Fragment 가 나오도록 한다.
그런 다음에 A와 B Fragment root view 에 Clickable 속성을 true 값을 준다.
위와 같이하면, B Fragment 로 이동 후, A Fragment 버튼 리스너가 먹히지 않는 것을 확인할 수 있다.
다시 정리하면?
1. replace > add + addToBackStack 으로 변경
2. xml 상위 root view 에 clickable 속성에 true 값을 주기