如何将 Compose LazyColumn 与协程/房间数据库结合使用?

dba*_*nes 3 android kotlin kotlin-coroutines android-jetpack-compose

我正在为自己编写一个简单的应用程序,以将 RSS 提要显示为项目列表,并认为这是一个了解@Compose lazyColumn. 我对它的代码之少感到震惊,没有 Adapter,没有 ViewHolder,没有 xml。令人惊讶的精简。

但是,如何将其设置为与Room Database使用协程从数据库中提取数据之类的情况一起工作呢?这里的官方文档讨论了rememberCoroutineScope()但没有解释在哪里定义它。将协程放置在 Surface 定义中感觉很奇怪,这可能就是它不起作用的原因。它会产生一个:@Composable invocations can only happen from the context of a @Composable function错误。

这需要通过a 来完成吗ViewModel?在现实世界中,存储库中的数据无论如何都将来自ViewModel,但现在我只想显示从互联网上提取的简单项目列表(即需要协程)。但是你如何处理ViewModel/Database 中的LiveDataor 呢?List<String>

有谁知道如何设置这个?我觉得这应该不难,但我不知道从哪里开始寻找答案。

前任:

class MainActivity : AppCompatActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContent {
           MyAppTheme {

               val composeScope = rememberCoroutineScope()
               Surface(color = MaterialTheme.colors.background) {
  
                    composeScope.launch{ // do network call
                        RssList(RssFetcher.fetchRss())  // how do you make this work?
                    }
               }
           }
       }
   }
}

@Composable
fun RssList(list: List<RssItems>){
   LazyColumn{ items(list) ... }
}
Run Code Online (Sandbox Code Playgroud)

Phi*_*hov 5

@Composable
fun TestView(
) {
    var rssList by remember { mutableStateOf(emptyList<RssItems>()) }
    LaunchedEffect(Unit) {
        rssList = RssFetcher.fetchRss()
    }
    RssList(rssList) 
}

@Composable
fun RssList(list: List<RssItems>){
    LazyColumn{ items(list) ... }
}
Run Code Online (Sandbox Code Playgroud)

要了解这里发生的情况,您需要查看:

  1. 在 compose 中存储状态。remember { mutableStateOf() }是在重组之间存储数据的最简单方法。但是当您在视图之间切换时它会被清理,因此也请检查视图模型,这可能更适合您的任务。文档
  2. LaunchedEffect是在可组合函数内执行任何操作的首选方式。在这个块中,您已经处于协程中,因此可以运行suspend函数
  3. 您不需要为 定义协程rememberCoroutineScope,它返回预初始化的协程。通常您需要将其用于按钮按下或触摸等事件