Fragment간에 데이터를 공유하는 몇 가지 방법에 대해 적어보고자 한다.
물론 틀린 부분이 있을 수도 있다💦
1. Bundle()
fragment의 데이터 전달은 많은 사람들이 bundle을 사용해서 처리해왔다.
사용 방법은 다음과 같다.
val testFragment = TestFragment()
val bundle = Bundle()
bundle.putString("id", et_id.text.toString())
testFragment.arguments = bundle
parentFragmentManager.beginTransaction)
.replace(R.id.fragment_container, testFragment())
.commit()
//ReceiveFragment
var restult = arguments?.getString("id")
2. Navigation SafeArgs
JetPack 라이브러리중 Navigation을 이용하면 복잡한 Fragment의 이동과 데이터 전달을 가시적이고 효율적으로 작성할 수 있다.
2021.03.10 - [Android] - Navigation으로 Fragment를 전환시켜보자!
Navigation으로 Fragment를 전환시켜보자!
Navigation In JetPack 보통 Activity의 전환은 Intent, Fragment의 전환은 transaction을 사용했다. Jetpack 라이브러리 내의 Navigation을 이용하면 프래그먼트간의 전환을 구현할 수 있다. 1. dependency 추가..
peaceful-coding-diary.tistory.com
navigation_graph를 통해 Fragment간의 Action과 Data 전달을 정의할 수 있다.
<fragment
android:id="@+id/homeFragment"
android:name="com.example.lecturesopt28th.home.view.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home" >
<argument
android:name="id"
app:argType="string" />
<action
android:id="@+id/action_homeFragment_to_repositoryFragment"
app:destination="@id/repositoryFragment" />
</fragment>
위와 같이 Fragment에 전달받고 싶은 데이터 형식을 argument로 선언해놓고
해당 Fragment로 전화할 때 형식에 맞는 데이터를 보내주면 된다.
데이터를 수신할 때는 by navArgs() 속성 위임을 사용하여 argument에 액세스할 수 있다.
///Pass Data
private fun login() {
binding.buttonLogin.setOnClickListener {
if(checkInputText()) {
Toast.makeText(requireContext(), "Please input email or password", Toast.LENGTH_SHORT).show()
} else {
val action =
LogInFragmentDirections.actionLogInFragmentToHomeFragment(viewModel.id.value!!)
Navigation.findNavController(binding.root).navigate(action)
}
}
}
//Receive Data
private val args: HomeFragmentArgs by navArgs()
viewModel.userId.value = args.id
3. ViewModel을 이용한 데이터 공유
같은 부모를 가진 Fragment에서는 ViewModel을 이용하면 데이터를 공유하기 수월하다.
하나의 Activity에 여러 Child Fragment들이 존재하면 ActivityViewModel을 이용하여 Fragment간에 데이터를 공유할 수 있다.
이 방법이 편리하긴 하지만 같은 자원을 공유한다는 것은 그만큼 결합도가 높아진다는 것이기 때문에 설계를 잘해야한다.
private val viewModel by activityViewModels<SharedViewModel>()
or
private val viewModel: SharedViewModel by activiyViewModels()
그렇다면 ParentFragment 하위에 여러 개의 ChildeFragment가 있다면 어떻게 해야할까?
여기서도 ActivityViewModel을 만들어 공유할 수 있지만, 이 방식으로 한다면 ParentFragment가 소멸되어도 ViewModel은 살아있어 버리기 때문에 적합하지 않다.
하지만 똑같은 방식으로 이렇게 사용하면 된다.
//Parent Fragment
private val viewModel by viewModels()
//Child Fragment
private val viewModel by viewModels(ownerProducer = {requireParentFragment().requireParentFragment()})
'Android' 카테고리의 다른 글
| [Jetpack Compose] State (0) | 2022.04.22 |
|---|---|
| Jetpack Compose로 마이그레이션하기 (1) (0) | 2022.04.20 |
| [Android] Dependency kotlin 코드로 관리하기(buildSrc) (0) | 2021.04.09 |
| [Android] Navigation Backstack Controll and Pass Data (0) | 2021.04.06 |
| [Android] Multi Select Gallery만들기 with Paging (0) | 2021.04.05 |