Android

(Android Studio) - Fragment 데이터 전달 방식

돗개진 2024. 4. 1. 11:13

[ Fragment 간 데이터 전달 방법 ]

1. bundle과 FragmentManager 로 전달

2. Fragment Result API를 사용하여 Data 전달

3. Fragment 간 공통의 ViewModel (ex. HostActivity 의 ViewModel) 로 전달

4. Jetapack 의 Navigation 에서 제공하는 safe-args 로 전달

 


 

1. bundle과 FragmentManager 로 전달 (Bundle 로 Data 를 담아 전달)

//PassBundleFragment는 본인이 전달하고자 하는 Fragment class
 val bundle = Bundle()
 bundle.putString("key", "value")
 
val passBundleBFragment = PassBundleBFragment()
passBundleBFragment.arguments = bundle parentFragmentManager.beginTransaction()
	.replace(R.id.fragment_container_bundle, PassBundleFragment())
	.commit()

ㄴ> 전송 측 Fragment class 코드

 

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
	var result = arguments?.getString("key")
	
    	return inflater.inflate(R.layout.fragment_pass_b, container, false)
    }

ㄴ> 받는 측 Fragment class 코드

 

 

 

2. Fragment Result API를 사용하여 Data 전달

2020년 androidx.fragment:fragment-ktx:1.3.0-alpha 버전에 도입된 기능

 

//PassBundleFragment는 본인이 전달하고자 하는 Fragment class
//fragment_container_bundle은 본인의 Fragment가 담겨있는 Container
button.setOnClickListener {
    val result = "result"
    setFragmentResult("requestKey", bundleOf("bundleKey" to result))
    parentFragmentManager.beginTransaction()
       .replace(R.id.fragment_container_bundle, PassBundleFragment())
       .commit()
}

ㄴ> 전송 측 Fragment class 코드

 

 

setFragmentResultListener("requestKey") { requestKey, bundle ->
        val result = bundle.getString("bundleKey")
        // Do something with the result
    }

ㄴ> 받는 측 Fragment class 코드

 

 

3. Fragment 간 공통의 ViewModel (ex. HostActivity 의 ViewModel) 로 전달

: 하나의 Activity 에서 container 로 여러 Fragment 를 이동하는 경우 사용 가능, Fragment 가 Activity 하위에 위치하기 때문에 사용할 수 있음. Acitivy 를 공유하는 여러 Fragment 들은 Activity 의 메모리를 공유할 수 있고 AAC 의 Viewmodel 은 Activity 의 ViewModel 을 사용하여 데이터 전달 가능.

구조도: 공통의 메모리 데이터를 이용하여 서로의 데이터를 전달하는 방법

 

class ViewModelPassActivity : AppCompatActivity() {
    val viewModel : PassingViewModel by viewModels()
}

class PassAFragment : Fragment() {
    val viewModel : PassingViewModel by activityViewModels()
}

class PassBFragment : Fragment() {
    val viewModel: PassingViewModel by activityViewModels()
}

ㄴ> Activity 에 Fragment 들이 같은 데이터를 바라볼 수 있게 ViewModel 객체를 만들고 그 객체에 데이터를 전달하여 간단하게 Fragment 통신 달성 가능.

 

 

 

4. Jetapack 의 Navigation 에서 제공하는 safe-args 로 전달

: Jetpack 의 Navigation 을 사용하는 프로젝트에서 적용하기 좋은 방법.

(장점: navigation.xml 에서 화면전환에 필요한 액션과 data를 정의할 수 있음, defaultValue 도 정의 가능 => 간결하고 안정적인 처리가 가능)

(단점: 다른 Data 전달 방식보다 환경세팅 하는 것이 많고 알아야 할 기능이 많음 ,단지 Fragment Data 전달을 위해 Navigation을 쓰는 것은 비효율적, 전체 프로젝트에 Navigation을 적용해야 이점이 많음)

 

// Navigation.xml에서 이동할 화면에 대한 정의(action)와 전달할 데이터(argument)를 정의
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_graph"
    app:startDestination="@id/passArgsAFragment">

    <fragment
        android:id="@+id/passArgsAFragment"
        android:name="com.gunt.fragmentdatapassexample.pass.passargs.PassArgsAFragment"
        android:label="PassArgsAFragment" >
        <action
            android:id="@+id/passAToB"
            app:destination="@id/passArgsBFragment"
            app:launchSingleTop="true" />
        <argument
            android:name="argsString"
            app:argType="string"
            android:defaultValue=""/>
    </fragment>
    <fragment
        android:id="@+id/passArgsBFragment"
        android:name="com.gunt.fragmentdatapassexample.pass.passargs.PassArgsBFragment"
        android:label="PassArgsBFragment" >
        <action
            android:id="@+id/passBToA"
            app:destination="@id/passArgsAFragment"
            app:launchSingleTop="true"
            app:popUpTo="@id/nav_graph" />
        <argument
            android:name="argsString"
            app:argType="string"
            android:defaultValue=""/>
    </fragment>
</navigation>

ㄴ> 전달 방식 설정

 

 

// 액션에 본인이 보내려는 데이터를 담아 액션을 수행
binding.btnSend.setOnClickListener {
            val action = PassArgsAFragmentDirections.passAToB(binding.etText.text.toString())
            findNavController().navigate(action)
        }

ㄴ> 전송 측 Fragment class 코드

 

 val args: PassArgsAFragmentArgs by navArgs()
 binding.textView.text = args.argsString

ㄴ> 받는 측 Fragment class 코드

 


 

https://developer.android.com/guide/fragments/communicate?hl=ko

 

프래그먼트와 통신  |  Android 개발자  |  Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 프래그먼트와 통신 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 프래그먼트를 재사용하려면 자체

developer.android.com

 

https://developer.android.com/guide/navigation/use-graph/pass-data?hl=ko

 

대상 간 데이터 전달  |  Android 개발자  |  Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 대상 간 데이터 전달 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 탐색을 사용하면 대상 인수를 정

developer.android.com