我正在构建一个简单的应用程序,它有一个带有两个选项卡的TabLayout。一个选项卡是一个项目列表,您可以单击该列表并记录该项目。另一个选项卡是您在第一个选项卡中所做的注释列表。
我已经使用TabRows和HorizontalPager创建了一个TabRows和HorizontalPager,这是该部分的代码:
@OptIn(ExperimentalPagerApi::class)
@Composable
fun HorizontalPagerTabLayout(
modifier: Modifier
) {
val tabData = listOf("Records" to Icons.Default.Phone, "Notes" to Icons.Default.Star)
val pagerState = rememberPagerState(
initialPage = 0
)
val tabIndex = pagerState.currentPage
val coroutineScope = rememberCoroutineScope()
Column {
TabRow(
selectedTabIndex = tabIndex,
modifier = modifier
) {
tabData.forEachIndexed { index, _ ->
Tab(
icon = {
Icon(imageVector = tabData[index].second, contentDescription = null)
},
selected = tabIndex == index,
onClick = {
coroutineScope.launch {
pagerState.animateScrollToPage(index)
}
},
text = {
Text(
tabData[index].first,
color = if (pagerState.currentPage == index) Color.White else Color.LightGray
)
})
}
}
HorizontalPager(state = pagerState, count = tabData.size) { page ->
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
when (page) {
0 -> RecordsScreen(modifier = Modifier)
1 -> NotesScreen(modifier = Modifier)
}
}
}
}
}
在RecordScreen中,我有一个逻辑,它将对记录做一个注释,并将其存储在RoomDB中。这就像预期的那样。
在 NotesScreen 中,我有一个viewModel,它将从RoomDB中提取所有注释,并在NotesScreen选项卡中播放它们。
下面是NotesScreen的代码:
@Composable
fun NotesScreen(
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
modifier: Modifier,
notesViewModel: NotesViewModel = hiltViewModel()
) {
val notesList by notesViewModel.notesStateData.collectAsState()
// FAILED SOLUTION NUMBER 2
// LaunchedEffect(Unit){
// notesViewModel.getAllNotes()
// }
// FAILED SOLUTION NUMBER 3
// DisposableEffect(lifecycleOwner) {
// val observer = LifecycleEventObserver { _, event ->
// when (event) {
// Lifecycle.Event.ON_RESUME -> {
// notesViewModel.getAllNotes()
// }
// else -> {}
// }
// }
// lifecycleOwner.lifecycle.addObserver(observer)
// onDispose {
// lifecycleOwner.lifecycle.removeObserver(observer)
// }
// }
LazyColumn(
contentPadding = (PaddingValues(horizontal = 16.dp, vertical = 8.dp)),
modifier = modifier
) {
items(items = notesList.orEmpty()) { note ->
NoteItem(note)
}
}
}
从代码中可以看到,我注释掉了一些失败的解决方案。我的第一个解决方案是在notesViewModel.getAllNotes()的init{}块中包含viewModel。但是这只调用了函数一次,而不是每次我回到NotesScreen时。
我的第二个解决方案是创建一个LaunchedEffect(Unit),因为我希望每次显示viewModel函数时都调用这个NotesScreen函数。但是它没有工作,它也只调用了一次getAllNotes()。
我的第三个解决方案是创建一个带有观察者的DisposableEffect,每当ON_RESUME发生时,它都会告诉我,但这也不起作用。
我使用调试器并记录了一些行为:
的HorizontalPager会加载屏幕。
当我使用
我想要的行为:每次我打开NotesScreen时,我都想加载来自RoomDB的所有注释,而不仅仅是在应用程序启动时加载一次。我正在尝试触发VM函数,它不需要刷新布局或按钮就能自动从DB获得注释,但我似乎找不到解决方案。
任何帮助都将不胜感激。
发布于 2022-07-20 07:34:22
您可以使用snapshotFlow添加页面更改回调到寻呼机。它从可观察到的快照状态创建一个流。下面是一个示例代码
// Page change callback
LaunchedEffect(pagerState) {
snapshotFlow { pagerState.currentPage }.collect { page ->
when (page) {
0 -> viewModel.getAllNotes() // First page
1 -> // Second page
else -> // Other pages
}
}
}
https://stackoverflow.com/questions/73034912
复制相似问题