iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0

上一篇講了如何建立一個Room database
這一篇要將原本的資料變成SQL的資料流,並替換部分邏輯

在ViewModel中使用

先把原本viewmodel中使用到todoList的部份去掉,並添加查詢函數(group name, todo list)

// SQL query  
fun getGroupTodo(group: String): Flow<List<TodoItem>> {  
    return todoDao.getGroupItems(group)  
}  
fun getGroupInfo(): Flow<List<GroupInfo>> {  
    return todoDao.getGroupsInfo()  
}
  
// TodoList  
fun submitTodo(todoItem: TodoItem): Boolean {  
    // Check valid  
    if (todoItem.group == "" || todoItem.title == "") return false  
    if (_isUpdate.value){ // update  
        todoDao.update(todoItem)  
        _isUpdate.update { false }  
    }  
    else // insert  
        todoDao.insert(todoItem)  
    return true  
}  
  
fun checkedTodo(todoItem: TodoItem, checked: Boolean) {  
    todoDao.update(todoItem.copy(done = checked))  
}

之後就可以把todoList刪除了
檢查各個有出問題的UI函數

TodoDisplay

val group by globalVM.currentGroup.collectAsState()  
val todoList by globalVM.getGroupTodo(group).collectAsState(emptyList())

並將items裡的filter去除

TodoGroups

@Composable  
fun TodoGroups(  
    globalVM: GlobalVM,  
    navController: NavController) {  
    val groupList by globalVM.getGroupInfo().collectAsState(emptyList())  
  
    LazyColumn{  
        items(items = groupList) { groupInfo->  
            GroupItem(groupInfo) {  
                globalVM.focusGroup(groupInfo.group)  
                navController.navigate(Screens.Main.Todos.route){  
                    launchSingleTop = true  
                }  
            }
		}
	}
}

GroupItem這邊就不展示了

InputPage

val groupNameList by globalVM.getGroupInfo().collectAsState(emptyList())
// DropDownMenu
DropDownSelector(  
    groupNameList.map { it.group },  
    group,  
)

這樣資料取得的地方就改得差不多了

更改ViewModel的宣告方式

因為我們自定義了ViewModel產生的方式,所以也要特別進行宣告

@Composable  
fun App(modifier: Modifier = Modifier) {  
    val navController = rememberNavController()  
    // DB construct(reference)  
    val context = LocalContext.current  
    val todoDB = Room.databaseBuilder(  
        context,  
        AppDatabase::class.java,  
        "todoDB",  
    ).build()  
    val todoDao = todoDB.todoDao()  
    val globalVM: GlobalVM = viewModel(  
        factory = GlobalViewModelFactory(todoDao)  
    )

這段看不懂也沒關係
現在啟動程式會發現一個todo都沒有,因為是資料庫剛建立,但當你想要add一下之後就會跳出
其實是因為資料庫存取有可能會阻斷主程式的運行,導致UI卡住,為了避免這種問題,所以就會跳出
這時候就要使用Coroutine呼叫
在所有使用到insert或update的地方套上

// at checked todo
viewModelScope.launch(Dispatchers.IO) {  
    todoDao.update(todoItem.copy(done = checked))  
}

現在就可以正常運行了


上一篇
Day 22:開始用Room建立表
下一篇
Day 24:紀錄零碎信息,使用DataStore
系列文
現代Android jetpack compose開發入門25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言