我已经用Compose课程完成了大部分Android基础知识,只需要做工作管理器和视图,但我已经完成了房间部分,并试图将其应用到我的第一个应用程序中,这是一个愚蠢的随机鼓舞士气的生成器.
每次打开应用程序时,我都会让一切都能生成一个新的对话,但我无法让我的按钮工作来允许用户生成新的对话.我也相信这其中有很多是可以优化的,并希望得到反馈,但目前我的重点是基本功能.
这是刀的一部分
@Query("SELECT saying from phrases WHERE type = 'greeting' ORDER BY RANDOM() LIMIT 1")
fun getGreeting(): Flow<String?>
@Query("SELECT saying from phrases WHERE type = 'first' ORDER BY RANDOM() LIMIT 1")
fun getFirst(): Flow<String?>
@Query("SELECT saying from phrases WHERE type = 'second' ORDER BY RANDOM() LIMIT 1")
fun getSecond(): Flow<String?>
@Query("SELECT saying from phrases WHERE type = 'ending' ORDER BY RANDOM() LIMIT 1")
fun getEnding(): Flow<String?>`
然后在存储库中(我相信这是可以改进的)
fun getNewTalk(): Flow<String> {
val greeting: Flow<String?> = phraseDao.getGreeting()
val first: Flow<String?> = phraseDao.getFirst()
val second: Flow<String?> = phraseDao.getSecond()
val ending: Flow<String?> = phraseDao.getEnding()
val firstHalf = greeting.combine(first) { greeting, first ->
"$greeting $first"
}
val secondHalf = second.combine(ending) { second, ending ->
"$second $ending"
}
val currentTalk = firstHalf.combine(secondHalf) {firstHalf, secondHalf->
"$firstHalf $secondHalf"
}
return currentTalk
}
和视图模型
class PepTalkScreenViewModel (
private val pepTalkRepository: PepTalkRepository
) : ViewModel() {
val currentTalk = pepTalkRepository.getNewTalk()
companion object {
val Factory: ViewModelProvider.Factory = viewModelFactory {
initializer {
val application = (this[APPLICATION_KEY] as PepTalkApplication)
val pepTalkRepository = application.pepTalkRepository
PepTalkScreenViewModel(pepTalkRepository = pepTalkRepository)
}
}
}
}
和主屏幕
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PepTalkScreen(
modifier: Modifier = Modifier
){
val pepTalkViewModel: PepTalkScreenViewModel = viewModel(factory = PepTalkScreenViewModel.Factory)
val pepTalk by pepTalkViewModel.currentTalk.collectAsState(initial = "")
//I've also tried collectAsStateWithLifecycle(initialValue = "") but no change in behavior
Scaffold (
.....
PepTalkCard(pepTalk = pepTalk)
.....
bottomBar = { BottomAppBar(pepTalk = pepTalk)}
脚手架中是对可组合卡片的函数的调用
@Composable
fun PepTalkCard(
pepTalk: String,
modifier: Modifier = Modifier
){
Card(
modifier = modifier
.fillMaxSize()
){
Text(
text = pepTalk,
style = MaterialTheme.typography.displayMedium,
modifier = Modifier
)
}
}
脚手架还调用底部的应用程序栏,其中有一个用于生成新对话的按钮和一个用于分享的按钮,这就是我的问题所在.为了让它再次查询DAO,我try 了onClick部分中的一些令人头疼的东西,但找不到我遗漏了什么.
@Composable
fun BottomAppBar (
pepTalk: String,
modifier: Modifier = Modifier
){
val pepTalkViewModel: PepTalkScreenViewModel = viewModel(factory = PepTalkScreenViewModel.Factory)
Row(
modifier = Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
//region New Button
Button(onClick = {
pepTalkViewModel.currentTalk
}) {
我认为调用变量curentTalk会刷新单词,因为它等于存储库中的函数.我试过做可变状态的东西,和实时数据,总是有一些东西抱怨没有匹配正确的类型,比如StateFlow来流动,感觉这应该不是一件复杂的事情.我已经在谷歌上搜索了几天了,有很多方法可以做到这一点,而且最佳实践似乎已经随着时间的推移而发生了变化,特别是在Compose方面.
任何向好的方向提供的帮助或指导都将不胜感激.