如何在MVVM android应用程序中使用存储库模式和实时数据对列表进行正确排序?
我正在为android编写一个简单的待办事项列表风格的应用程序,我在添加排序功能方面遇到了问题 我有一个屏幕,屏幕上显示了属于用户的所有列表,我想添加一个功能,允许用户打开或关闭排序。问题是,我似乎无法找到一种方法,使显示给用户的列表在再次更改后保持一致的排序 假设列表保存在如何在MVVM android应用程序中使用存储库模式和实时数据对列表进行正确排序?,android,sorting,mvvm,viewmodel,repository-pattern,Android,Sorting,Mvvm,Viewmodel,Repository Pattern,我正在为android编写一个简单的待办事项列表风格的应用程序,我在添加排序功能方面遇到了问题 我有一个屏幕,屏幕上显示了属于用户的所有列表,我想添加一个功能,允许用户打开或关闭排序。问题是,我似乎无法找到一种方法,使显示给用户的列表在再次更改后保持一致的排序 假设列表保存在房间数据库中。 实现我想要的最简单、最一致的方法是对数据库本身中的数据进行排序,但这可能不是一种方法,因为实现起来会很复杂(如果可能的话) 我很可能应该在视图模型中对数据进行本地排序。我想我可以使用MediatorLiveD
房间
数据库中。
实现我想要的最简单、最一致的方法是对数据库本身中的数据进行排序,但这可能不是一种方法,因为实现起来会很复杂(如果可能的话)
我很可能应该在视图模型中对数据进行本地排序。我想我可以使用MediatorLiveData
来实现这一点,它将观察数据库,而主机活动则会观察数据库本身。在更新MediatorLiveData
之前,我会使用标记isSorting
对列表进行排序,以原样返回数据或在传递结果之前对其进行排序
我的问题的关键是,我希望能够打开和关闭此功能,同时在之后(当执行另一个操作时)仍然保持数据的顺序。以下是一个典型事件流的示例:
class UserListsViewModel(val userId:Int,val repository:ListsRepository):ViewModel(){
val allLists=MediatorLiveData()
val isSorting=false
初始化{
allLists.addSource(repository.getAllUserList(userId)){userLists->
val结果=用户列表
如果(i排序){
result=result.sortedBy{it.name}
}
值=结果
}
}
}
现在让我们进入实际问题:
只要打开排序功能,一切正常,用户将看到“列表1”、“列表2”、“列表3”、“列表4”
但是现在,假设用户关闭了排序功能,并添加了另一个列表,“列表0”
现在发生的是:
MediatorLiveData
接收来自数据库的更新,即“列表3”、“列表1”、“列表2”、“列表4”、“列表0”(数据库的原始顺序,加上新列表)isSorting
标志处于关闭状态,因此它会按原样设置返回数据的值谢谢我认为你的假设有问题 现在让我们进入实际问题: 只要打开排序功能,一切正常,用户将看到“列表1”、“列表2”、“列表3”、“列表4” 但是现在,假设用户关闭了排序功能,并添加了另一个列表,“列表0” [……] 期望结果:“列表1”、“列表2”、“列表3”、“列表4”、“列表0”(未排序,但保留以前的顺序) 实际结果:“列表3”、“列表1”、“列表2”、“列表4”、“列表0”(列表1、2、3之前的排序现在丢失) 作为用户,我希望在打开或关闭排序后立即更改排序行为。因此,在用户关闭排序后,项目的显示顺序将再次为:“列表3”、“列表1”、“列表2”、“列表4”。当添加另一个列表时,它将(不进行排序)追加到末尾,就像您编写的那样,但不会对用户进行意外的排序更改 如果您真的想实现上面描述的功能,我想您必须在表中添加一个
sort\u index
字段作为排序标准。然后,当您按列表标题、创建日期等进行排序时,可以更新该字段。然后,当您按此字段排序时(您也可以让room/数据库为您排序,这样会更高效),用户将获得应用程序的一致行为
更高级的方法是创建一个额外的“映射”表,其中有一列用于列表索引,另一列用于实际顺序(sort\u index
)。当然,该列表也可以保存在视图模型中,而不是数据库中的字段/表,因为它可以动态创建
使用此字段的另一个好处是,它允许您的用户通过拖放手动排序列表,您只需相应地更新索引。这是我遇到的另一个问题,也是我决定采用的解决方案(希望这能帮助其他人): 首先,我采用了建议的方法,即在用户单击“排序”按钮后立即更改排序顺序。这意味着,我不再按照“现在是它的排序,现在不是”,而是将其视为“数据总是按某些东西排序(即使它是“未排序的”)。 我希望“未排序”列表(默认排序)与数据库中显示的项目的顺序相同,但是我的
ViewModel
的设置方式使我无法
class ListsRepository {
val db = Database().getInstance();
fun getAllUserLists(userId: Int): LiveData<List<UserList>>
}
class UserListsActivity: Activity() {
val viewModel: UserListsViewModel
val adapter: UserListAdapter
fun onCreate(savedInstanceState: Bundle?) {
viewModel.allLists.observe(this, Observer { newData ->
adapter.setData(newData)
adapter.notifyDataSetChanged()
)
}
}
class UserListsViewModel(val userId: Int, val repository: ListsRepository ): ViewModel() {
val allLists = MediatorLiveData<List<UserList>>()
val isSorting = false
init {
allLists.addSource(repository.getAllUserLists(userId)) { userLists ->
val result = userLists
if(isSorting) {
result = result.sortedBy { it.name }
}
value = result
}
}
}
//inside view model class
val allLists : LiveData<List<UserList>> = repository.getAllLists()