![](/img/trans.png)
[英]Ui Not recomposing when deleting items from room database in jetpack compose
[英]Jetpack Compose: Room returns null for list of items
我正在嘗試使用 livedata 從數據庫中獲取待辦事項列表,但是在調試時它總是顯示 null 的值。 我在下面提供了我的文件。
我的道:
@Query("SELECT * FROM todo_table WHERE IIF(:isCompleted IS NULL, 1, isCompleted = :isCompleted)")
fun getTodos(isCompleted: Boolean?): LiveData<List<Todo>>
我的視圖模型:
private var _allTodoList = MutableLiveData<List<Todo>>()
var allTodoList: LiveData<List<Todo>> = _allTodoList
init {
viewModelScope.launch(Dispatchers.IO) {
val list = todoRepository.getTodos(null)
_allTodoList.postValue(list.value)
}
}
fun onFilterClick(todoType: Constants.TodoType) {
when (todoType) {
Constants.TodoType.ALL -> {
viewModelScope.launch(Dispatchers.IO) {
val list = todoRepository.getTodos(null)
_allTodoList.postValue(list.value)
}
}
Constants.TodoType.COMPLETED -> {
viewModelScope.launch(Dispatchers.IO) {
val list = todoRepository.getTodos(true)
_allTodoList.postValue(list.value)
}
}
Constants.TodoType.INCOMPLETE -> {
viewModelScope.launch(Dispatchers.IO) {
val list = todoRepository.getTodos(false)
_allTodoList.postValue(list.value)
}
}
}
}
我的主要活動:
val allTodoList = viewModel.allTodoList.observeAsState()
allTodoList.value?.run {//value is always null
if (!isNullOrEmpty()) {
...
} else {
...
}
}
在調試時我發現allTodoList.value
始終是 null 但是,當我在應用程序檢查中手動運行相同的查詢時,我得到了想要的結果。
你可以簡化你的代碼,看看它是否有效。 ViewModel 只需要這個:
val allTodoList: LiveData<List<Todo>> = todoRepository.getTodos(null)
主要活動:
val allTodoList by viewModel.allTodoList.observeAsState()
if (!allTodoList.isNullOrEmpty()) {
...
} else {
...
}
您沒有觀察從 Room 獲得的 LiveData。 YourDao.getTodos()
和LiveData.getValue()
不是掛起函數,因此您獲得的是當前值,即 null,因為 Room 尚未從 SQLite 獲取值。
一種可能的解決方案是將待辦事項類型設置為實時數據本身,並在 ViewModel 中使用 switchMap 轉換:
private val todoType = MutableLiveData<Constants.TodoType>(Constants.TodoType.ALL)
val allTodoList: LiveData<List<Todo>> = androidx.lifecycle.Transformations.switchMap(todoType) { newType ->
val typeAsBoolean = when(newType) {
Constants.TodoType.ALL -> null
Constants.TodoType.COMPLETED -> true
Constants.TodoType.INCOMPLETE -> false
else -> throw IllegalArgumentException("Not a possible value")
}
// create the new wrapped LiveData
// the transformation takes care of subscribing to it
// (and unsubscribing to the old one)
todoRepository.getTodos(typeAsBoolean)
}
fun onFilterClick(todoType: Constants.TodoType) {
// triggers the transformation
todoType.setValue(todoType)
}
這實際上是參考文檔中演示的確切用例
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.