有一个基地Room。LiveData我通过and得到了整个列表ViewModel。
道:
@Query("SELECT * FROM tasks")
fun getAllTask(): LiveData<List<Tasks>>
存储库:
fun getAllTasks(tasksDao: TasksDao): LiveData<List<Tasks>> {
this.tasksDao = tasksDao
return tasksDao.getAllTask()
}
视图模型:
class OwnViewModel(application: Application) : AndroidViewModel(application) {
private val repository: OwnRepository
val allTasks:LiveData<List<Tasks>>
init {
val tasksDao = AppDatabase.getDatabase(application, viewModelScope).tasksDao()
repository = OwnRepository()
allTasks = repository.getAllTasks(tasksDao)
}
}
分段:
class TasksFragment : Fragment() {
private lateinit var ownViewModel: OwnViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ownViewModel = ViewModelProviders.of(this).get(OwnViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_tasks_list, container, false)
val recyclerView = view.findViewById<RecyclerView>(R.id.listTasks)
// Set the adapter
val adapter = MyTasksRecyclerViewAdapter(listener, context!!)
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(context)
ownViewModel.allTasks.observe(viewLifecycleOwner, Observer { tasksList ->
tasksList?.let {
adapter.setTaskList(it)
}
})
return view
}
}
我将结果列表传递给适配器并填写RecyclerView
需要从同一个表中获取一个不完整的列表,但通过某些参数过滤。
事实上,现在随着数据库的变化,适配器将收到一个带有变化的新列表。但是获取过滤列表的正确方法是什么?
我想出了几个选择。
第一个选项- 逻辑上应该这样做 - 是从基础获取与参数对应的新元素列表,someId例如,通过这样的请求:
@Query("SELECT * FROM tasks WHERE some_id = :someId")
fun getTaskBySomeId(someId: Long): LiveData<List<Tasks>>
然后传递给Repository,然后传递给 ,然后传递ViewModel给adapter。但是当您尝试进行此传输并替换适配器中的列表时,会出现很多不一致的情况。例如,我正在尝试分支。如果filterIsTrue == true那时我请求截断列表:
重新设计的 ViewModel:
class OwnViewModel(application: Application) : AndroidViewModel(application) {
private val repository: OwnRepository
val allTasks: LiveData<List<Tasks>>
init {
val tasksDao = AppDatabase.getDatabase(application, viewModelScope).tasksDao()
repository = OwnRepository()
allTasks = getTasksList(tasksDao)
}
private fun getTasksList(tasksDao: TasksDao): LiveData<List<Tasks>> {
if (filterIsTrue) {
return repository.getFilteredTasks(tasksDao, someId)
} else {
return repository.getAllTasks(tasksDao)
}
}
}
LiveData但显然没有订阅新的,所以列表没有更新。有一个想法是杀死旧的并获得一个新的LiveData并进行另一个订阅。我不确定这是否可行,这是一个非常令人困惑的代码。
第二种选择是制作两个LiveData,然后在适当的时候切换。但是后来我将有 2 个订阅,每次我都会收到 2 个列表ViewModel:完整和部分 - 不合理,但更容易。您可以取消不必要的订阅并订阅新的订阅LiveData,但这更加困难并且仍然ViewModel会收到 2 个列表。
第三个选项是通过适配器中已有的参数或在将其传递给适配器之前从完整列表中进行选择。不难,但是使用数据库的本质就丢失了。事实证明,我每次都会收到一个完整的列表,然后对其进行迭代,而不是从数据库中获取一个小列表并使用它。
最好的组织方式是什么?
为了不创建新的 LiveData 并且不返回拐杖,我们为其创建了一个 getter,因此我们总是获得与 Fragment 中的 Observer 订阅相同的 LiveData 实例:
与其使用变量,不如创建两个方法来获取排序或常规列表,这样会更简单明了,然后我们只需通过 value 分配我们的 LiveData 列表,然后 Observer 接收新数据并更新 UI。
如果您不打算跟踪其中的更改,则无需从 Room 返回 LiveData:
我可以建议你阅读谷歌关于应用程序架构的文章(有源链接)
如果需要跟踪数据库,可以使用以下方法:
每次触发器更改时,都会在某个存储库中调用一些方法 + 我们的观察者将订阅一个 liveData 实例,该实例将从存储库接收数据。