簡體   English   中英

Jetpack Compose:Room 返回 null 以獲取項目列表

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM