Fragment간 데이터 전달하는 방법에 대한 기본적인 개념과 간단한 예제는 아래 블로그에다가 정리를 해뒀었다
https://coding-juuwon2.tistory.com/256
이번에는 예제를 통해 직접 코드를 짜보려고한다
Fragment간 데이터 전달하는 방식은 여러가지가 있는데 일단 가장 기본적인? 3가지 방법을 사용해볼것이다
1. Bundle 에 담아서 데이터 전달
2. ViewModel를 사용하여 데이터 공유(전달)
3. Fragment Reslut API를 통해서 데이터 전달
1.Bundle 에 담아서 데이터를 전달
bundle을 사용해서 데이터를 전달해주면 된다
// 1. Bundle 사용해서 전달
binding.sendBtn.setOnClickListener {
// 데이터리스트 가져옴
val dataSoure = DataSource.getDataSoures().getFlowerList()
val dashboardFragment = DashboardFragment()
val bundle = Bundle()
bundle.putString("name1", dataSoure.get(0).name)
bundle.putString("description1", dataSoure.get(0).description)
Log.d(TAG, dataSoure.get(0).name)
Log.d(TAG, dataSoure.get(0).description)
dashboardFragment.arguments = bundle
parentFragmentManager.beginTransaction()
.replace(R.id.main_framelayout, dashboardFragment)
.commit()
}
HomeFragment.kt (데이터 전달할 프래그먼트)
데이터를 받아올때는 arguments를 사용해서 받아와준뒤, 레이아웃에 뿌려준다
(안드로이드는 프래그먼트 생성과 동시에 데이터를 전달하거나 받을 수 있는 arguments를 제공함)
// 1. bundle로 보낸 데이터 받아오기
val name = arguments?.getString("name").toString()
val description = arguments?.getString("description").toString()
binding.flowerNameContentTv.text = "꽃이름: $name"
binding.flowerDescriptionContentTv.text = "설명: $description"
DashboardFragment.kt (데이터 받을 프래그먼트)
# 실행화면
-> HomeFragment에서 전달버튼을 누르면 dashboardFragment로 이동하고 데이터까지 잘 전달되는것을 확인할 수 있다
근데 dashboardFragment를 벗어나면 데이터가 저장되지 않고 사라진다..!
2. ViewModel를 사용하여 데이터 공유
viewModel을 프래그먼트끼리 공유해서 사용해야지, 프래그먼트간 데이터공유가 가능하다
Activity를 공유하는 여러 Fragment들은 Activity의 메모리를 공유할 수 있고 AAC의 ViewModel은 Activity의 lifecycle보다 오래 살아있는 것이 보장되기 때문에 안전하게 공통의 Activity의 ViewModel을 사용하여 데이터 전달이 가능하다.
먼저 viewModel을 생성해줘야한다
viewModel을 생성해준뒤, 각 Fragment가 전송,수신할 데이터를 입력값으로 받아오는 함수를 작성해준다
class FlowerViewModel : ViewModel() {
val flowerData = MutableLiveData<String>()
// 전송할 데이터
fun sendFlowerData(name : String, description : String){
flowerData.value = name
flowerData.value = description
}
}
FlowerViewModel.kt
데이터 전달할 프래그먼트에서는 아래와 같은 코드를 설정해줌으로써 Fragment간에 데이터를 공유할 수 있게 된다
이때 파라미터에 this대신 requireActivity()를 사용해주도록하자 (this를 사용하면 두 프래그먼트는 서로다른 엑티비티를 갖게되서 데이터 공유를 하지 못한다. requireActivity()를 사용해야지 두 프래그먼트가 같은 엑티비티를 갖게되서 데이터 공유가 가능하게된다 )
flowerViewModel = ViewModelProvider(requireActivity()).get(FlowerViewModel::class.java)
// 2. viewModle 사용해서 데이터 전달
// 데이터리스트 가져옴
val dataSoure = DataSource.getDataSoures().getFlowerList()
flowerViewModel = ViewModelProvider(requireActivity()).get(FlowerViewModel::class.java)
binding.sendBtn2.setOnClickListener {
flowerViewModel.sendFlowerData("name", dataSoure.get(1).name)
flowerViewModel.sendFlowerData("description", dataSoure.get(1).description)
parentFragmentManager.beginTransaction()
.replace(R.id.main_framelayout, NotificationsFragment())
.commit()
}
DashboardFragment.kt (데이터 전달할 프래그먼트)
// viewModel로 전달한 데이터 받아와서 뿌려주기
val dataSoure = DataSource.getDataSoures().getFlowerList()
val flowerModel = ViewModelProvider(requireActivity()).get(FlowerViewModel::class.java)
flowerModel.flowerData.observe(viewLifecycleOwner, Observer {
binding.flowerNameContentTv2.text = "꽃이름: ${dataSoure.get(1).name}"
})
flowerModel.flowerData.observe(viewLifecycleOwner, Observer {
binding.flowerDescriptionContentTv2.text = "설명: ${dataSoure.get(1).description}"
})
NotificationsFragment.kt (데이터 받을 프래그먼트)
# 실행화면
-> dashboardFragment에서 전달버튼을 누르면 NotificationsFragment로 이동하고 데이터까지 잘 전달되는것을 확인할 수 있다
bundle과는 다르게 해당 프래그먼트를 벗어나도 데이터가 잘 유지되는것을 볼수있다!
데이터가 잘 유지되는것을 보니 이방법이 제일 유용한 방법인것같다
그치만 앱을 나갔다가 들어오면 이 방식도 데이터가 다 사라져있는데, 앱을 나갔다가 들어와도 데이터가 유지되도록하려면 데이터베이스를 사용해줘야될것같다
3. Fragment Reslut API를 통해서 데이터 전달
먼저 의존성을 추가해줘야한다
build.gradle에 아래와 같이 코드를 추가해주자
// Result API
implementation ("androidx.fragment:fragment-ktx:1.6.2")
build.gradle.kt
데이터를 받는 프래그먼트에서는 FragmentManager에 setFragmentResultListener("requestKey") 메소드를 사용하여 주어진 requestKey로 리스너를 설정해준다.
아래 코드에서는 requestKey를 Name과 Description으로 설정해줬다
// 3. Result API 사용해서 보낸 데이터 받아옴
setFragmentResultListener("Name") { requestKey, bundle ->
val name = bundle.getString("name")
binding.flowerNameContentTv3.text = "꽃이름: $name"
}
setFragmentResultListener("Description") { requestKey, bundle ->
val description = bundle.getString("description")
binding.flowerDescriptionContentTv3.text = "설명: $description"
}
HomeFragment.kt (데이터 받을 프래그먼트)
데이터를 전달하는 프래그먼트에서는 setFragmentResult("requestKey", Bundle) 메소드를 사용하여 주어진 requestKey로 데이터를 저장해준다
그러면 데이터가 FragmentManager를 통해서 동일한 requestKey로 리스너를 등록한 HomeFragment로 전달된다
// 3. Result API를 사용해서 데이터 전달
binding.sendBtn3.setOnClickListener {
setFragmentResult("Name", bundleOf("name" to dataSoure.get(2).name))
setFragmentResult("Description", bundleOf("description" to dataSoure.get(2).description))
parentFragmentManager.beginTransaction()
.replace(R.id.main_framelayout, HomeFragment())
.commit()
}
NotificationsFragment.kt (데이터 전달할 프래그먼트)
# 실행화면
-> NotificationsFragment에서 전달버튼을 누르면 HomeFragment로 이동하고 데이터까지 잘 전달되는것을 확인할 수 있다
그치만 얘도 bundle처럼 데이터가 저장되지는 않는다..!
# 참고자료
https://sohee1702.tistory.com/600
https://moon-i.tistory.com/entry/Fragment-Result-API
'개발 노트 > Kotlin' 카테고리의 다른 글
[Android/Kotlin] ImageView scaleType 속성 (0) | 2024.04.12 |
---|---|
[Android / Kotlin] Intent로 Class 값 넘기기 (Serializable, Parcelable, Parcelize) (0) | 2024.04.12 |
[Android / Kotlin] Recyclerview에 구분선 표시 (0) | 2024.04.11 |
[Android/Kotlin] 어댑터 콜백을 위한 Lambda 함수 전달 (0) | 2024.04.10 |
[Android/Kotlin] Activity, Fragment간 데이터 주고받기 (0) | 2024.04.10 |