1

我在 Jetpack DataStore 中保存了选项菜单复选框项(选中/未选中)的状态:

override fun onOptionsItemSelected(item: MenuItem) =
    when (item.itemId) {
        R.id.action_hide_completed_tasks -> {
            item.isChecked = !item.isChecked
            viewModel.hideCompleted(item.isChecked)
            true
        }
        else -> super.onOptionsItemSelected(item)
    }

调用此方法:

suspend fun updateHideCompleted(hideCompleted: Boolean) {
    dataStore.edit { preferences ->
        preferences[PreferencesKeys.HIDE_COMPLETED] = hideCompleted
    }
}

现在我想在我的片段出现在屏幕上时恢复此复选框状态。但是由于 Jetpack DataStore 以 a 的形式提供用户首选项Flow,这感觉有点 hacky。我从中收集FlowonPrepareOptionsMenu使用take(1)运算符只执行一次,因为之后我不再需要从首选项中更新复选框,当我单击选项菜单项时状态会自动更改:

override fun onPrepareOptionsMenu(menu: Menu) {
    lifecycleScope.launch {
        viewModel.preferencesFlow
            .take(1) // I want this to update only when the fragment comes onto the screen, afterward it's unnecessary
            .collect {
                menu.findItem(R.id.action_hide_completed_tasks).isChecked = it.hideCompleted
            }
    }
}

这是正确的方法吗?感觉有点hacky。在某些情况下,异步性会导致问题吗?

4

1 回答 1

4

我相信正确的方法是使用Flow<T>.first()操作员。

override fun onPrepareOptionsMenu(menu: Menu) {
    lifecycleScope.launch {
        val value = viewModel.preferencesFlow.first()
        menu.findItem(R.id.action_hide_completed_tasks).isChecked = value.hideCompleted
    }
}
于 2020-12-06T15:56:13.533 回答