🎉 Fragment
프래그먼트는 액티비티 처럼 화면을 구성하는 뷰입니다. 액티비티에 작성할 수 있는 모든 코드를 프래그먼트에 사용할 수 있단 뜻입니다 ! 하지만 프래그먼트 단독으로는 사용할 수 없기 때문에 항상 액티비티 내에서 호스팅 되야 하며 액티비티 라이프 사이클에 직접적인 영향을 받습니다.
🤔그럼 액티비티를 놔두고 굳이 프래그먼트를 사용하는 이유가 뭘까요?
프래그먼트를 처음 도입한건 Android 3.0(API Lv 11) 부터였습니다. 프래그먼트는 테블릿이나 큰 화면에서 동작할 수 있는 앱을 개발하기 위해 제공되었습니다. 하나의 화면은 하나의 액티비티에서 만들어져야 하는데 화면이 크면 하나의 액티비티 클래스에 너무 많은 코드를 작성한다는 문제가 있었기 때문이죠.
아래 그림은 왼쪽에 목록을 보여주는 프래그먼트와 그 목록에서 항목을 선택하면 오른쪽에 상세 내용을 출력되는 예 입니다. 이 모든 내용을 Activity 하나에 모두 담긴 부담스럽겠죠? 그래서 두 화면을 각각 분리해서 작성하면 좀 더 유지보수 측면에서 유연성이 생길 수 있습니다.
🎉 Fagment Life Cycle
Activity Life Cycle과 비교했을 때 추가된 몇가지 콜백 함수를 확인할 수 있습니다. 생성 프로세스에서는 onCreateView(), onViewCreated(), onViewStateRestored() 함수가 있고 종료 프로세스에선 onDestroyView() 가 추가 됐습니다.
View Life Cycle 관점에서 Fragment Life Cycle을 단계로 나눠 살펴보겠습니다.
- 초기화(initalized) : onAttach(), onCreate()에서 아직 View를 사용할 수 없으므로 View와 관련 없는 프래그먼트의 초기화 로직을 수행합니다.
- 생성(created) : onCreateView, onViewCreated()에서 Fragment 화면을 구성할 View를 준비합니다. onCreateView() 함수의 파라미터로 LayoutInflater 객체가 전달되므로 대부분 onCreateView 함수에서 Fragment 화면을 구성할 View 객체를 준비합니다.
- 시작(started) : Fragment가 사용자에게 보여집니다.
- 재개(resumed) : 포커스를 가지고 사용자의 이벤트를 처리할 수 있습니다.
- 소멸(destoryed) : 벡 스택(Back Stack : Fragment가 화면에 보이지 않는 순간 제거하지 않고 저장했다 다시 이용)의 사용 여부에 따라 생명 주기가 다르게 동작합니다.
Back Stack 사용 : onPause() -> onStop() -> onDestroyView -> 사용자가 화면을 다시킴 -> onCreateView() -> onViewCreated() -> onStart() -> onResume()
Back Stack 미사용 : onPause() -> onStop() -> onDestroyView -> onDestory -> onDetach
🎉 Fagment Life Cycle Callback Method
onAttach
Fragment가 FragmentManager에 추가 되고 Host Activity에 연결될 때 호출되며 이 시점에 Fragment가 활성화 되고 FragmentManager가 Fragment의 생명주기를 관리합니다.
override fun onAttach(context: Context) {
super.onAttach(context)
}
onCreate
Fragment만 생성되고 이 시점엔 아직 Fragment View가 생성되지 않기 때문에 Fragment의 View와 관련된 작업을 수행해선 안됩니다. onCreate 콜백 시점엔 savedInstanceState 파라미터를 전달받는데 이는 onSaveInstanceState() 콜백 함수에 의해 저장된 Bundle 값입니다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
onCreateView
Fragment가 View를 그리기 위한 작업 즉 Layout을 inflate 하는 작업을 수행하고 따라서 반환 값도 View가 됩니다. 아래 예시는 Fragment에서 ViewBinding을 하는 예시입니다. return 값으로 이 Fragment Layout XML FILE의 가장 최상위 요소 즉, Fragment를 반환합니다.
class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding ?= null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
}
}
onViewCreated
onCreateView에서 반환된 View 객체를 파라미터로 전달받습니다. 이 시점 부터는 Fragment View의 LifeCycle이 Initialized 상태로 변하기 때문에 View의 초기값을 설정하거나 Live Data Observing, Adapter 초기화 등의 작업을 이곳에서 작업하는 것이 적절합니다.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
onStart
Fragment 가 사용자에게 보여질 수 있을 때 호출됩니다. 이 시점부터 Fragment의 child FragmentManager 통해 FragmentTransaction 을 안전하게 수행할 수 있습니다.
override fun onStart() {
super.onStart()
}
onResume
사용자와 상호 작용하고 각종 이벤트를 처리할 수 있습니다.
override fun onResume() {
super.onResume()
}
onPause
사용자가 Fragment를 떠나기 시작했지만 Fragment는 여전히 보이는 상태입니다.
override fun onPause() {
super.onPause()
}
onStop
Fragment가 더이상 화면에 보이지 않으면 Fragment와 View의 LifeCycle은 CREATED 상태가 됩니다. 이 상태는 Fragment의 Parent Activity나 Fragment가 중단됐을 때 뿐만 아니라 Parent Activity나 Fragment의 상태가 저장될 때도 호출됩니다.
API 28 버전을 기점으로 onSaveInstance() 함수와 onStop() 함수의 호출 순서가 달라졌는데 onStop() 이 onSaveInstanceState() 함수보다 먼저 호출됨으로써 onStop() 이 FragmentTransaction 을 안전하게 수행할 수 있는 마지막 지점이 되었습니다.
override fun onStop() {
super.onStop()
}
onDestoryView()
Fragment가 화면에서 완전히 벗어났을 경우 Fragment와 연결된 View가 제거 중 일 때 호출되며 가비지 컬렉터에 의해 수거될 수 있도록 Fragment View에 대한 모든 참조가 제거되어야 합니다.
override fun onDestroyView() {
super.onDestroyView()
}
onDestroy()
Fragment 가 제거되거나 FragmentManager 가 destroy 됐을 경우, 프래그먼트의 Lifecycle 은 DESTROYED 상태가 되고 Fragment Lifecycle 의 끝을 알립니다. 또한 메모리 누수 방지를 위해 바인딩했던 리소스를 해제하였습니다.
override fun onDestroy() {
super.onDestroy()
_binding = null
}
'Android' 카테고리의 다른 글
Anroid Jetpack [ ViewBinding ] (0) | 2024.01.02 |
---|---|
Android LayoutInflater (1) | 2023.12.26 |
Android Activity Life Cycle (3) | 2023.12.26 |
Android Platform Architecture (0) | 2023.12.25 |
Android Main Thread (2) | 2023.12.23 |