当我在 ViewModel 中使用 LiveData 时,为什么数据不持久?
Why doesn't the data persist when I use LiveData in the ViewModel?
我正在使用Navigation Component
切换屏幕。
在底部 A
菜单的片段屏幕中,我可以通过按钮动态添加 recyclerview
项。
如果我按下此屏幕上的按钮,它会移动到另一个可以select编辑数据的片段。
如果我 select 转换后的片段屏幕上的数据,它 returns 到前一个屏幕并根据 selected 数据添加 recycler view item
。
重复这个过程。
但是,即使我重复这个过程,也不会动态添加该项目。
我使用 ViewModel
将项目添加到 LiveData
的 List
,但作为调试的结果, LiveData
的 size of the list type
确实不是只增加一个。
至少据我所知应该保留数据,因为使用 viewmodel
不受 lifecycle
.
的影响
但是我遇到的问题是因为换屏好像每次都初始化保存了
这是为什么?
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")
item.setSubItemList(detailItem)
_items.value?.add(item)
_items.value = _items.value
}
}
片段
class WriteRoutineFragment : Fragment() {
private var _binding : FragmentWriteRoutineBinding? = null
private val binding get() = _binding!!
private lateinit var adapter : RoutineAdapter
private val args : WriteRoutineFragmentArgs by navArgs()
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)
args.workout?.let { workout ->
vm.addRoutine(workout)
Toast.makeText(context, workout, Toast.LENGTH_SHORT).show()
}
vm.items.observe(viewLifecycleOwner) { updatedItems ->
adapter.setItems(updatedItems)
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
更新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" />
<argument
android:name="workout"
app:argType="string"
app:nullable="true"
android:defaultValue="@null"/>
</fragment>
视图模型应该有一个 activity 范围,以便视图模型能够在整个 activity 生命周期中存在。
视图模型必须这样初始化,
private val model: SharedViewModel by activityViewModels()
这个确切的用例在 Android Docs
中有详细解释
我正在使用Navigation Component
切换屏幕。
在底部 A
菜单的片段屏幕中,我可以通过按钮动态添加 recyclerview
项。
如果我按下此屏幕上的按钮,它会移动到另一个可以select编辑数据的片段。
如果我 select 转换后的片段屏幕上的数据,它 returns 到前一个屏幕并根据 selected 数据添加 recycler view item
。
重复这个过程。
但是,即使我重复这个过程,也不会动态添加该项目。
我使用 ViewModel
将项目添加到 LiveData
的 List
,但作为调试的结果, LiveData
的 size of the list type
确实不是只增加一个。
至少据我所知应该保留数据,因为使用 viewmodel
不受 lifecycle
.
但是我遇到的问题是因为换屏好像每次都初始化保存了
这是为什么?
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")
item.setSubItemList(detailItem)
_items.value?.add(item)
_items.value = _items.value
}
}
片段
class WriteRoutineFragment : Fragment() {
private var _binding : FragmentWriteRoutineBinding? = null
private val binding get() = _binding!!
private lateinit var adapter : RoutineAdapter
private val args : WriteRoutineFragmentArgs by navArgs()
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)
args.workout?.let { workout ->
vm.addRoutine(workout)
Toast.makeText(context, workout, Toast.LENGTH_SHORT).show()
}
vm.items.observe(viewLifecycleOwner) { updatedItems ->
adapter.setItems(updatedItems)
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
更新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" />
<argument
android:name="workout"
app:argType="string"
app:nullable="true"
android:defaultValue="@null"/>
</fragment>
视图模型应该有一个 activity 范围,以便视图模型能够在整个 activity 生命周期中存在。
视图模型必须这样初始化,
private val model: SharedViewModel by activityViewModels()
这个确切的用例在 Android Docs
中有详细解释