在 Navhost 导航期间,我发现可组合屏幕多次重新组合。因此,我的 ViewModel 也多次调用 API 数据源。
@Composable
fun MainView() {
val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
val scope = rememberCoroutineScope()
val navController = rememberNavController()
Scaffold(
scaffoldState = scaffoldState,
topBar = { TopBar(
toolbarTitle = stringResource(id = R.string.app_name),
scope = scope,
scaffoldState = scaffoldState
) },
drawerContent = {
DrawerView(scope = scope, scaffoldState = scaffoldState, navController = navController)
},
) {
NavGraph(navController = navController)
}
}
@Composable
fun NavGraph(navController: NavHostController) {
NavHost(navController, startDestination = NavDrawerItem.Repositories.route) {
composable(NavDrawerItem.Repositories.route) {
RepoListView(getViewModel())
}
composable(NavDrawerItem.EmojiList.route) { …Run Code Online (Sandbox Code Playgroud) android android-jetpack-navigation android-jetpack-compose jetpack-compose-navigation compose-recomposition
我在我的应用程序中使用 Navigation-Compose :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeTheme {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Screens.Dashboard.title) {
composable(Screens.Dashboard.title) {
DashboardScreen(navController)
}
composable(
Screens.Section.title, arguments = listOf(
navArgument(LINK) {
type = AssetParamType()
}
)
) {
SectionDetailsScreen(navController)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我在每个屏幕上都有一个单独的应用程序栏,例如:
@Composable
fun DashboardScreen(
navController: NavHostController,
viewModel: DashboardViewModel = hiltViewModel()
) {
Scaffold(
topBar = {
TopAppBar(
title = {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
) {
Text(text = stringResource(id …Run Code Online (Sandbox Code Playgroud) 我正在尝试打开一个撰写详细信息页面,其中使用 hiltviewmodel() 添加了 Viewmodel 该视图模型具有分页数据状态和 API 调用结果状态,需要它来显示更新的数据以及列表。但是当我导航到详细信息页面时,viewmodel 方法被多次调用,甚至 init {} 块也被调用。有人遇到过类似的问题吗,或者有什么解决办法吗?
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun DashboardScreen(
navController: NavController,
dashboardViewModel: DashboardViewModel = hiltViewModel(),
Name: String = ""
) {
val lazyArticleList = dashboardViewModel.articlePages.collectAsLazyPagingItems()
val dashState = dashboardViewModel.dashboardState.value
}
Run Code Online (Sandbox Code Playgroud) 我正在使用 Jetpack Compose + Navigation(单一活动,无片段),并且我正在尝试执行如下导航路线:
SplashScreen---(延迟)---> AuthScreen---(如果成功)-->MainScreen
navigate()不幸的是,当我执行登录时,可组合项中的函数LoginScreen会导致无限循环。我不明白我是否正在触发重组或会发生什么。不幸的是,很难共享所有代码,但请记住:
LoginScreen可MainScreen组合项无关(您可以假设它们只是一个简单的Text可组合项)NavigationGraph。事实上,如果我只是进行SplashScreen-->MainScreen转换,就不会出现问题navController.navigate("main")则不再有循环;这是AuthScreen出现问题的代码。
@Composable
fun AuthScreen(navController: NavController) {
val signInRequestCode = 1
val context = LocalContext.current
val mSignInViewModel: SignInGoogleViewModel = viewModel(
factory = SignInGoogleViewModelFactory(context.applicationContext as Application)
)
val state = mSignInViewModel.googleUser.observeAsState()
val user = state.value
val isError = rememberSaveable { mutableStateOf(false) }
val authResultLauncher =
rememberLauncherForActivityResult(contract …Run Code Online (Sandbox Code Playgroud) infinite-loop android-jetpack-navigation android-jetpack-compose
我设置了导航、分页并使用流程将 ui 与模型连接起来。如果简化的话,我的屏幕代码如下所示:
@Composable
MainScreen() {
val listState = rememberLazyListState()
val lazyItems = Pager(PagingConfig(...)) { ... }
.flow
.cachedIn(viewModelScope)
.collectAsLazyPagingItems()
LazyColumn(state = listState) {
items(lazyItems, key = { it.id }) { ... }
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的 NavHost 代码:
NavHost(navController, startDestination = "mainScreen") {
composable("mainScreen") {
MainScreen()
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我从另一个屏幕导航回主屏幕或只是打开抽屉时,数据会再次从数据源加载,并且我会看到明显的闪烁LazyColumn。
如何避免重新加载数据?