A->B로 화면을 전환할때 String 데이터를 넘깁니다. Navigation Graph의 action와 safeargs를 활용합니다.
B에서는 A에서 받은 데이터를 해당화면의 타이틀로 설정합니다.
B에서 C로 화면전환을 하고 C화면에서 어떤 버튼을 클릭하면서 다시 B 화면으로 돌아가는 기능입니다.
(여기서 C에서도 D로 데이터를 보내야하지만 아직 구현은안했습니다)
그런데 C에서 B로 돌아오면, A에서 B로 화면전환이 된것이 아니기 때문에 B의 argument 값은
nav_graph에서 설정했던 디폴트 값으로 설정이 됩니다..
이것을 화면이 계속해서 전환되어도 어떻게 유지할 수 있을까요?
nav_graph.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/calendar">
<!-- 화면 A -->
<dialog
android:id="@+id/bodyPartDialog"
android:name="com.example.writeweight.fragment.BodyPartDialogFragment"
android:label="BodyPartDialogFragment"
tools:layout="@layout/fragment_body_part_dialog">
<action
android:id="@+id/action_bodyPartDialog_to_write"
app:destination="@id/write"/>
</dialog>
<!-- 화면 B -->
<fragment
android:id="@+id/write"
android:name="com.example.writeweight.fragment.WritingRoutineFragment"
android:label="WritingRoutineFragment"
tools:layout="@layout/fragment_writing_routine">
<argument
android:name="title"
app:argType="string"
android:defaultValue="" />
<action
android:id="@+id/action_write_to_workoutListTabFragment"
app:destination="@id/workoutListTabFragment" />
</fragment>
<!-- 화면 C -->
<fragment
android:id="@+id/workoutListTabFragment"
android:name="com.example.writeweight.fragment.WorkoutListTabFragment"
android:label="fragment_workout_list_tab"
tools:layout="@layout/fragment_workout_list_tab" >
<action
android:id="@+id/action_workoutListTabFragment_to_write"
app:destination="@id/write"
app:popUpTo="@id/write"
app:popUpToInclusive="true"/>
</fragment>
</navigation>
화면 A
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view: View = inflater.inflate(R.layout.fragment_body_part_dialog, container, false)
startBtn?.setOnClickListener { v ->
if (BodyPartCustomView.getSelectedCount() == 0) Toast.makeText(context, "부위를 선택해주세요", Toast.LENGTH_SHORT).show()
else {
title = BodyPartCustomView.getTitle()
// safeargs를 이용한 작성페이지로 title 데이터 전달
action = BodyPartDialogFragmentDirections.actionBodyPartDialogToWrite(title)
findNavController()?.navigate(action)
BodyPartCustomView.clearTitleData() // companion 타입이므로 초기화
dismiss()
}
}
return view
}
화면 B
class WritingRoutineFragment : Fragment() {
private var _binding: FragmentWritingRoutineBinding? = null
private val binding get() = _binding!!
private val viewModel: WriteRoutineViewModel by viewModels { WriteRoutineViewModelFactory() }
private val args by navArgs<WritingRoutineFragmentArgs>() // argument 받음.
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
_binding = FragmentWritingRoutineBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.title.observe(viewLifecycleOwner) { titleData -> // viewmodel 의 title 값이 변경됐을때 titleData 로 넘어옴
// UI 업데이트
binding.title.text = titleData // 타이틀 세팅
}
viewModel.setValue(args) // 뷰모델에 받은 argument 값 넣기
}
}
화면 B의 ViewModel
class WriteRoutineViewModel : ViewModel() {
private var _title: MutableLiveData<String> = MutableLiveData()
val title: LiveData<String> = _title
fun setValue(_data: WritingRoutineFragmentArgs) {
_title.value = _data.title
}
}