【发布时间】:2021-08-31 18:03:06
【问题描述】:
我正在使用嵌套的 recyclerview。
图中red box是Routine Item (Parent Item),blue box是日常项目中的Detail Item (Child Item)。
您可以通过点击ADD ROUTINE button动态添加parent item。
同样,child items可以通过点击parent item的ADD button动态添加。
因此,这个函数工作得很好。
但问题出在我写的代码上。
我使用ViewModel 来观察和更新父项添加/删除。
但是,它不会观察到父项中详细项的变化。
我认为这是因为LiveData 只检测到列表的添加和删除。
所以我放了_items.value = _items.value 代码,以便在添加和删除子项时可以观察到它。
这样,我什至不必在child adapter 中使用像notifyDataSetChanged() 这样的更新代码。
最终成功了,但不知道这是否是正确的代码。
如果您需要其他代码,请告诉我!
在 Fragment.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)
getTabPageResult()
// RecyclerView Update
vm.items.observe(viewLifecycleOwner) { updatedItems ->
adapter.setItems(updatedItems)
}
}
private fun getTabPageResult() {
val navController = findNavController()
navController.currentBackStackEntry?.also { stack ->
stack.savedStateHandle.getLiveData<String>("workout")?.observe(
viewLifecycleOwner, Observer { result ->
vm.addRoutine(result) // ADD ROUTINE
stack.savedStateHandle?.remove<String>("workout")
}
)
}
}
private fun addDetail(pos: Int) {
vm.addDetail(pos)
}
private fun deleteDetail(pos: Int) {
vm.deleteDetail(pos)
}
}
ViewModel
class WriteRoutineViewModel : ViewModel() {
private var _items: MutableLiveData<ArrayList<RoutineModel>> = MutableLiveData(arrayListOf())
val items: LiveData<ArrayList<RoutineModel>> = _items
fun addRoutine(workout: String) {
val item = RoutineModel(workout, "TEST")
_items.value?.add(item)
// _items.value = _items.value
}
fun addDetail(pos: Int) {
val detail = RoutineDetailModel("TEST", "TEST")
_items.value?.get(pos)?.addSubItem(detail) // Changing the parent item's details cannot be observed by LiveData.
_items.value = _items.value // is this right way?
}
fun deleteDetail(pos: Int) {
if(_items.value?.get(pos)?.getSubItemSize()!! > 1)
_items.value?.get(pos)?.deleteSubItem() // is this right way?
else
_items.value?.removeAt(pos)
_items.value = _items.value // is this right way?
}
}
【问题讨论】:
标签: android kotlin android-recyclerview android-viewmodel