본문 바로가기

개발 노트/Kotlin

[Android/Kotlin] Fragment간 데이터통신(데이터전달)

Fragment간 데이터 전달하는 방법에 대한 기본적인 개념과 간단한 예제는 아래 블로그에다가 정리를 해뒀었다

https://coding-juuwon2.tistory.com/256

 

[Android] Fragment간 데이터통신 방식

1. FragmentManager에 Bundle로 Data를 담아 전달 //PassBundleFragment는 본인이 전달하고자 하는 Fragment class val bundle = Bundle() bundle.putString("key", "value") val passBundleBFragment = PassBundleBFragment() passBundleBFragment.argumen

coding-juuwon2.tistory.com

 

 

 

이번에는 예제를 통해 직접 코드를 짜보려고한다

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://velog.io/@blue-sky/Android-Fragment-to-Fragment-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EB%8B%AC

 

Android Fragment to Fragment 데이터 전달

Fragment to Fragment 데이터 통신

velog.io

https://jeonyt89.medium.com/android-fragment-%EA%B0%84-viewmodel-data-%EA%B3%B5%EC%9C%A0-39b489e8aaea

 

[Android] Fragment 간 ViewModel Data 공유

2개의 프레그먼트에서 Data를 공유해서 사용할 경우가 있다 Fragment1 : Message 전송 역할 ( Data 업데이트 ) Fragment2 : Message 수신후 보여주는 역할 ( Data 변화 감지 )

jeonyt89.medium.com

https://sohee1702.tistory.com/600

 

[Android] Fragment 간 ViewModel Data 공유

단일 액티비티에서 다수의 프레그먼트 사용시 같은 Data를 이용할 경우가 많다. 프레그먼트 별로 ViewModel 객체를 생성할 경우 데이터 공유가 어렵다. 해결방법 다수의 프레그먼트에서 Data를 공유

sohee1702.tistory.com

https://velog.io/@changhee09/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-Fragment-Activity-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EB%8B%AC

 

[안드로이드] Fragment - Activity 데이터 전달

안드로이드 - Fragment와 Activity간의 데이터 전달(ViewModel, Fragment Result API)

velog.io

https://moon-i.tistory.com/entry/Fragment-Result-API

 

Fragment Result API

* 공식문서 번역 Fragment 간 데이터 전달을 위해 viewModel을 사용하기도 하고, interface를 사용하기도 하고 여러 방법을 사용하는데 Activity Result 같이 Fragment Result도 있다고 한다.. 언제생겼지..! 어떤

moon-i.tistory.com