https://ibb.co/8BZcZVG (현재 앱 상황입니다)
WriteRoutineFragment.kt
class WriteRoutineFragment : Fragment() {
private var _binding : FragmentWriteRoutineBinding? = null
private val binding get() = _binding!!
private lateinit var adapter : RoutineAdapter
private val vm : WriteRoutineViewModel by viewModels { WriteRoutineViewModelFactory() }
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
_binding = FragmentWriteRoutineBinding.inflate(inflater, container, false)
adapter = RoutineAdapter(::addDetail, ::deleteDetail)
binding.rv.adapter = this.adapter
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
handleLoginForm()
vm.items.observe(viewLifecycleOwner) { updatedItems ->
adapter.setItems(updatedItems)
}
}
private fun handleLoginForm() {
val navController = findNavController()
val navBackStackEntry = navController.getBackStackEntry(R.id.writeRoutine)
// Create our observer and add it to the NavBackStackEntry's lifecycle
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME
&& navBackStackEntry.savedStateHandle.contains("selectedWorkout")) {
val result = navBackStackEntry.savedStateHandle.get<String>("selectedWorkout");
// Do something with the result
vm.addRoutine(result!!)
}
}
navBackStackEntry.lifecycle.addObserver(observer)
// As addObserver() does not automatically remove the observer, we
// call removeObserver() manually when the view lifecycle is destroyed
viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_DESTROY) {
navBackStackEntry.lifecycle.removeObserver(observer)
}
})
}
}
TabFrragment(데이터 프래그먼트)
class WorkoutListTabPageFragment : Fragment() {
private var _binding : FragmentWorkoutListTabPageBinding? = null
private val binding get() = _binding!!
private lateinit var adapter: WorkoutListAdapter
private lateinit var part: String
private val viewModel: WorkoutListViewModel by viewModels()
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
_binding = FragmentWorkoutListTabPageBinding.inflate(inflater, container, false)
binding.apply {
adapter = WorkoutListAdapter(::setNavResult)
rv.adapter = adapter
}
viewModel.setList(part) // 탭 부위에 맞는 운동리스트를 보여주기 위해 해당 부위 정보 전달
// setList()에서 part를 넣어 관찰해 탭도 swipe 할 때마다 업데이트
viewModel.part.observe(viewLifecycleOwner) { _ ->
adapter.addItems(viewModel.getList())
adapter.notifyDataSetChanged()
}
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// workout을 obeserve 하지 않으면 이 프래그먼트에 도착하고
// 값을 선택하지도 않고서 다시 바로 되돌아 가버리는 현상이 발생.
// previous~~ 코드가 이전화면으로 되돌리는것인지는 모르겠음
// 그래서 강제로 viewmodel 내에 workout LiveData를 설정함
// workout LiveData 자체는 아무 의미 없는 값이긴 하다.
viewModel.workout.observe(viewLifecycleOwner, Observer { workout ->
val navController = findNavController()
navController.previousBackStackEntry?.savedStateHandle?.set("key", "TEST")
navController.popBackStack()
})
}
private fun setNavResult(result: String) {
viewModel.setValue(result)
}
}
어댑터
inner class ViewHolder(itemView: View, context: Context) : RecyclerView.ViewHolder(itemView) {
private val tv: TextView = itemView.findViewById(R.id.workout)
init {
tv.setOnClickListener { view -> // 운동 선택
setVal("ser")
}
}
fun bind(item: String) {
tv.text = item
}
}
뷰모델
class WorkoutListViewModel(application: Application) : AndroidViewModel(application){
private var _part :MutableLiveData<String> = MutableLiveData()
private var _list : MutableLiveData<List<String>> = MutableLiveData(arrayListOf())
private val resources = application.resources
private var _workout :MutableLiveData<String> = MutableLiveData()
private val workoutListSource : WorkoutListSource by lazy { WorkoutListLocalSource(resources) }
val list = _list
val part = _part
val workout = _workout
fun setList(part : String) {
_part.value = part
when(_part.value) {
"가슴" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.CHEST)
"등" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.BACK)
"하체" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.LEG)
"어깨" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.SHOULDER)
"이두" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.BICEPS)
"삼두" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.TRICEPS)
"복근" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.ABS)
}
}
fun getList() : List<String> = list.value!!
fun setValue(result: String) { // 테스트 위함
_workout.value = result // workout의 값을 변화주기 위한 설정
}
}
Nav_graph
<fragment
android:id="@+id/writeRoutine"
android:name="com.example.lightweight.fragment.WriteRoutineFragment"
android:label="fragment_write_routine"
tools:layout="@layout/fragment_write_routine" >
<action
android:id="@+id/action_writeRoutineFragment_to_workoutListTabFragment"
app:destination="@id/workoutListTabFragment" />
</fragment>
<fragment
android:id="@+id/workoutListTabFragment"
android:name="com.example.lightweight.fragment.WorkoutListTabFragment"
android:label="WorkoutListTabFragment" >
<!-- <action-->
<!-- android:id="@+id/action_workoutListTab_to_writeRoutine"-->
<!-- app:destination="@id/writeRoutine"-->
<!-- app:popUpTo="@id/writeRoutine"-->
<!-- app:popUpToInclusive="true"/>-->
</fragment>