본문 바로가기
프로그래밍

ViewBinding 환경에서 부모 Fragment의 Arguments를 자식 Fragment에게 안전하게 전달하기 (완벽 가이드)

by Kongkongpapa 2025. 3. 21.
728x90
반응형
SMALL

Android 앱 개발에서 부모 Fragment 안에 자식 Fragment를 포함시키는 경우는 흔합니다. 이때 부모 Fragment의 arguments를 자식 Fragment에게 전달해야 하는 상황이 발생할 수 있습니다. 특히 ViewBinding을 사용하는 환경에서는 몇 가지 주의해야 할 점들이 있습니다. 이번 글에서는 ViewBinding 환경에서 부모 Fragment의 arguments를 자식 Fragment에게 안전하게 전달하는 다양한 방법들을 자세히 설명합니다.

문제 상황: 자식 Fragment의 onViewCreated() 호출 시점

ViewBinding 환경에서 부모 Fragment의 binding이 inflate될 때 자식 Fragment의 onViewCreated()가 호출될 수 있습니다. 이때 부모 Fragment의 arguments가 자식 Fragment에게 세팅되기 전에 호출되는 문제가 발생할 수 있습니다.

해결 방법

1. post() 또는 Handler를 사용하여 arguments 설정 지연

자식 Fragment의 onViewCreated()에서 post() 또는 Handler를 사용하여 arguments 설정을 지연시키는 방법입니다.

Kotlin
 
// ChildFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    binding.textView.post { // 또는 Handler 사용
        arguments = parentFragment?.arguments
        val data = arguments?.getString("key")
        binding.textView.text = data
    }
}

2. viewLifecycleOwner.lifecycle.addObserver()를 사용하여 생명주기 이벤트 감지

자식 Fragment의 viewLifecycleOwner의 생명주기 이벤트를 감지하여 onResume() 또는 onStart()와 같은 특정 시점에 arguments를 설정하는 방법입니다.

Kotlin
 
// ChildFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
        override fun onResume(owner: LifecycleOwner) {
            super.onResume(owner)
            arguments = parentFragment?.arguments
            val data = arguments?.getString("key")
            binding.textView.text = data
            viewLifecycleOwner.lifecycle.removeObserver(this) // 한 번만 실행되도록 observer 제거
        }
    })
}

3. findFragmentById()를 사용하여 자식 Fragment 인스턴스 가져오기

부모 Fragment에서 findFragmentById()를 사용하여 자식 Fragment 인스턴스를 가져온 후, arguments를 설정하는 방법입니다. 이 방법은 자식 Fragment가 이미 생성된 경우에만 사용할 수 있습니다.

Kotlin
 
// ParentFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    childFragmentManager.executePendingTransactions()

    val childFragment = childFragmentManager.findFragmentById(R.id.childFragment) as ChildFragment?
    childFragment?.arguments = arguments
}

4. ViewModel을 사용하여 데이터 공유 (권장)

부모 Fragment와 자식 Fragment가 공유하는 ViewModel을 사용하여 데이터를 공유하는 방법입니다. 이 방법은 arguments를 직접 전달하는 대신 ViewModel을 통해 데이터를 주고받습니다.

Kotlin
 
// SharedViewModel.kt
class SharedViewModel : ViewModel() {
    private val _data = MutableLiveData<String>()
    val data: LiveData<String> = _data

    fun setData(data: String) {
        _data.value = data
    }
}

// ParentFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    val viewModel = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
    viewModel.setData(arguments?.getString("key") ?: "")
}

// ChildFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    val viewModel = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
    viewModel.data.observe(viewLifecycleOwner) { data ->
        binding.textView.text = data
    }
}

권장하는 방법

가장 권장하는 방법은 ViewModel을 사용하여 데이터 공유하는 것입니다. ViewModel은 생명주기를 안전하게 관리하고, 데이터 공유를 위한 다양한 기능을 제공합니다.

하지만 arguments를 직접 전달해야 하는 경우에는 post() 또는 Handler를 사용하여 arguments 설정 지연시키는 방법을 사용할 수 있습니다.

결론

ViewBinding 환경에서 부모 Fragment의 arguments를 자식 Fragment에게 안전하게 전달하기 위해서는 자식 Fragment의 onViewCreated() 호출 시점을 고려하여 적절한 방법을 선택해야 합니다. ViewModel을 사용하는 것이 가장 권장되지만, 상황에 따라 다른 방법들을 사용할 수도 있습니다.

반응형
LIST