在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) {
EmojiListView(getViewModel())
}
}
}
class RepoListViewModel(
private val repositoriesUseCase: GetRepositoriesUseCase
): ViewModel() {
init {
getRepositories()
}
@Composable
fun RepoListView(viewModel: RepoListViewModel) {
AppTheme {
RepoListContent(viewModel)
}
}
有办法处理它吗?我的意思是,我知道这就是Android Compose的工作原理。但是,如何在导航屏幕中处理API调用?
编辑
问题出在Koin本身。一个新版本已经问世,现在运行正常。
如果您担心重组是导致多次网络调用的原因,您可以始终确保在具有LaunchedEffect的可组合生命周期中只调用viewModel一次。
因此,一种方法是:
LaunchedEffect(Unit) {
viewModel.getRepositories()
}
只要你传递到LaunchedEffect的关键帧没有改变,它就不会重新合成。因此,只要可堆肥是活的,使用Unit只会运行一次。
每次导航到该屏幕时,您是否都在重新创建viewModel?如果是这样的话,也许值得考虑将您的网络呼叫放在init
块之外的另一个地方,并使用上面的LaunchedEffect
方法,或者进行它,这样您就不会在每次导航中都重新创建您的viewModel。任何最适合您的用例。
获取compositable((lambda之外的viewModel。
@Composable
fun NavGraph(navController: NavHostController) {
val viewModel: RepoListViewModel = ViewModel()
NavHost(navController, startDestination = NavDrawerItem.Repositories.route) {
composable(NavDrawerItem.Repositories.route) {
RepoListView(viewModel)
}
composable(NavDrawerItem.EmojiList.route) {
EmojiListView(viewModel)
}
}
}
+如果您的getViewModel((使用ViewModelProvider检索ViewModel,则用对ViewModel((的调用替换getViewModel