* 공식문서 번역
Fragment 간 데이터 전달을 위해 viewModel을 사용하기도 하고, interface를 사용하기도 하고 여러 방법을 사용하는데 Activity Result 같이 Fragment Result도 있다고 한다.. 언제생겼지..!
어떤경우 사용하나
- 일회성 데이터를 fragment간, 혹은 fragment 와 host activity간 전달하고 싶을 때 사용한다.
Fragment 1.3.0-alpha04 이후부터 FragmentManager는 FragmentResultOwner를 구현한다. (상속받아)
이것은 Fragment Manager가 fragment 결과의 central store로 동작할수 있다는것을 의미한다.
이제 component간 직접 참조 하지 않고, fragment의 result를 설정하고, 결과를 수신 및 수신 대기해서 서로 데이터를 전달 할 수 있게됐다~
1. Fragment간 result 전달 하기
- Fragment B에서 Fragment A에게 데이터를 전달하기 하기 예제
- 먼저 Fragment A에 result Listener를 설정 - result를 받을 fragment
- Fragment A의 FragmentManager에서 setFragmentResultListener() 를 호출
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Use the Kotlin extension in the fragment-ktx artifact
setFragmentResultListener("requestKey") { requestKey, bundle ->
// We use a String here, but any type that can be put in a Bundle is supported
val result = bundle.getString("bundleKey")
// Do something with the result
}
}
- Fragment B에서는 result 를 생성한다.
- setFragmentResult() api를 이용해서 같은 FragmentManager에 같은 requestKey로 result를 set 한다
button.setOnClickListener {
val result = "result"
// Use the Kotlin extension in the fragment-ktx artifact
setFragmentResult("requestKey", bundleOf("bundleKey" to result))
}
- Fragment A 상태가 started될때 result를 받고, listener callback이 실행된다.
- 하나의 키에는 하나의 listener 결과만 있을 수 있다. 동일한 키에 setFragmentResult를 두번이상 호출하는 경우 시스템은 대기중인 결과를 업데이트된 결과로 변경한다. 리스너가 started상태가 아닌경우 동일
- 결과를 수신할 listener가 없이 setFragmentResult만 설정되어 결과가 있는경우, 동일한 키로 리스너가 설정될때까지 FragmnetManager에 결과가 저장된다.
- listener가 결과를 받고 onFragmentResult를 실행하면 결과는 삭제된다.
- BackStack에 있는 Fragment는 상태가 STARTED로 변경되기 전까지 결과를 받지 않는다
- 결과를 기다리는 fragment가 STARTED 상태이고, 결과가 설정되면 listener의 callback이 바로 실행된다.
2. Parent, Child Fragment간 result 전달하기
- 부모자식간의 결과 데이터를 주고받기 위해서는 setFragmentResultListener()가 호출될때 getChildFragmentManager를 사용해야한다 (getParentFragmentManager대신)
- ChildFragmentManager에 listener등록
- 자식은 FragmentManager에 결과 설정, 부모 fragment가 started상태가 되면 상위 fragment에서 결과를 수신
부모
// 부모 fragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// We set the listener on the child fragmentManager
childFragmentManager.setFragmentResultListener("requestKey") { key, bundle ->
val result = bundle.getString("bundleKey")
// Do something with the result
}
}
자식
button.setOnClickListener {
val result = "result"
// Use the Kotlin extension in the fragment-ktx artifact
setFragmentResult("requestKey", bundleOf("bundleKey" to result))
}
3. Host Activity에서 결과 받기
Host Activity에서 fragment result를 받으려면 getSupportFragmentManager()를 사용해서 fragment manager에 listener 설정
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager
.setFragmentResultListener("requestKey", this) { requestKey, bundle ->
val result = bundle.getString("bundleKey")
}
}
}
끝~
'Android' 카테고리의 다른 글
[Android] RecyclerView and DiffUtil (0) | 2022.02.26 |
---|---|
Firebase Cloud Messaging (FCM) - Android (0) | 2022.02.24 |
Android 에서 MVC, MVP, MVVM 예제로 공부하기 (0) | 2022.02.17 |
[Android] Room - Part of Android Jetpack (0) | 2022.02.13 |
Clean Architecture - Android에 적용하기 (0) | 2022.01.23 |