[Android/Kotlin] Activity와 Fragment에서의 화면 이동 및 스택 관리

코코아의 개발일지·2023년 9월 5일
0

Android-Kotlin

목록 보기
2/31
post-thumbnail

🤔 시작에 앞서..

첫 프로젝트를 할 때는 사실 아무것도 몰랐기에, 스택 관리를 별로 신경쓰지 않았다. 하지만 무작정 쌓기만 하다 보니 화면을 여러 번 이동한 뒤 뒤로가기 할 때마다 계속해서 이전 화면들이 보이는 문제가 있었다. 스택 관리에 힘써야하는 이유이다.


✍🏻 요구사항 분석

화면 이동할 때 쌓여있는 모든 Activity, Fragment의 스택을 없애야 할 때가 있다. 이를테면 로그아웃 후 로그인 화면으로 돌입해야하는 상황처럼 말이다. 나는 처음에 무작정 쌓기만 하고, 이를 없애는 방법을 알지 못했다! 그래서 각각의 경우를 오늘 정리해보려고 한다.

👇🏻 화면 이동 시의 데이터 전달에 대해 더 알고 싶다면?
[Android/Kotlin] 화면을 이동할 때 데이터를 전달하는 방법 총정리


💻 코드 작성

1️⃣ Activity

* 단순한 경우)

만약, A 액티비티 -> B 액티비티

startActivity(Intent(this, B_Activity::class.java))

식으로 이동했다면, 반대로 B 액티비티 -> A 액티비티로 돌아오고 싶다면

finish()

만 써주면 된다.

* 스택을 없앨 경우)

하지만, A 액티비티 -> B 액티비티로 이동하기 전에 이미 다른 액티비티가 쌓여 있는 상황이라면, 그리고 이를 종료하면서 한 번에 새로운 C 액티비티로 가고 싶다면,

startActivity(Intent(this, C_Activity::class.java))
finishAffinity()

를 쓰면 된다.
이렇게 하면 이미 쌓여있던 액티비티들을 모두 종료하면서 C 액티비티로 이동할 수 있다.


2️⃣ Fragment

프래그먼트의 경우, 앞선 Activity보다는 조금 더 복잡할 수 있다.

* Fragment -> Fragment 이동

같은 Activity 내의 Fragment일 경우에는

requireActivity().supportFragmentManager.beginTransaction()
            .add(R.id.login_setting_frm, AlertLoginFragment())
            .commitAllowingStateLoss()
  • 참고) Activity 내에서 Fragment를 교체할 때는, 위와 비슷하지만
supportFragmentManager.beginTransaction()
            .replace(R.id.main_frm, Fragment_Name())
            .commitAllowingStateLoss()

처럼, requireActivity()가 없어도 된다.


* Fragment -> Activity 이동

startActivity(Intent(requireActivity(), Activity_Name::class.java))
  • 참고) Activity 내에서 Fragment를 바꿀 때는
    위에서 Activity -> Activity에서
startActivity(Intent(this, C_Activity::class.java))

처럼 this를 썼던 것과 달리, Fragment에서는 this 대신 requireActivity()를 써야한다.
를 쓴다.


* 스택을 없앨 경우

A 액티비티에서 이미 다른 B 액티비티 내의 B 프래그먼트로 이동을 하며 스택이 쌓인 상황, 하지만 여기서 C 액티비티로 이동하면서 모든 스택을 없애주어야 한다면, B 프래그먼트에서 써야하는 코드는 다음과 같다.

activity?.finishAffinity()
startActivity(Intent(context, C_Activity()::class.java))

시작할 때 말한 로그아웃의 경우가 바로 이 경우였다.
MainActivity의 MyFragment에서 -> 로그아웃 버튼이 있는 MyBaseActivity의 MySettingFragment로 이동을 한 상황에서, 위의 코드를 써주면서 모든 스택을 지우고 로그인 화면으로 넘어갈 수 있었다.


+)

그리고, B 액티비티 내의 B 프래그먼트에서 B 액티비티를 종료하면서 A 액티비티로 돌아가야하는 상황도 생겼는데,
그냥 단순한 Fragment -> Activity 화면 이동이었다면 startActivity(Intent(requireActivity(), A_Activity::class.java))를 썼겠지만,
이 경우 내가 있는 액티비티를 종료하면서 다시 원래 있던 액티비티로 돌아가야 했기에 다른 방법이 필요했다. 이 경우 B 프래그먼트에서 쓸 수 있는 코드는

Intent(requireActivity(), MainActivity::class.java).apply {
	flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
}.also {
	startActivity(it)
}
activity?.finishAffinity()

이것이다!
앞의 경우와는 달리 코드를 이렇게 쓰는 이유는 이미 A 액티비티는 스택에 쌓여있는 상황인데, 앞의 경우처럼 finishAffinity() 후 바로 A 액티비티로 화면을 이동하면 에러가 나기 때문이다.
로그아웃의 경우에는 완전 새로운 C 액티비티(로그인) 화면으로 이동했기 때문에 이 에러가 발생하지 않는다.


👀 마치며

사실 프래그먼트와 액티비티가 계속 정신없게 나와서!
조금 헷갈릴 것 같지만 누구에겐가는 도움이 될거라 믿는다. 내가 처음에는 많이 헤맸듯이!

profile
우당탕탕 성장하는 개발자

0개의 댓글