Prevent screenModels being recreated when opening a screen from a tab

Do it the right way, solution from https://github.com/adrielcafe/voyager/issues/266#issuecomment-2002108371
This commit is contained in:
Shinokuni 2024-03-19 14:15:04 +01:00
parent c52f324a13
commit 093936b036
4 changed files with 12 additions and 13 deletions

View File

@ -3,10 +3,9 @@ package com.readrops.app.compose
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.material3.*
import cafe.adriel.voyager.navigator.CurrentScreen import cafe.adriel.voyager.navigator.CurrentScreen
import cafe.adriel.voyager.navigator.Navigator import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.navigator.NavigatorDisposeBehavior
import com.readrops.app.compose.account.selection.AccountSelectionScreen import com.readrops.app.compose.account.selection.AccountSelectionScreen
import com.readrops.app.compose.account.selection.AccountSelectionViewModel import com.readrops.app.compose.account.selection.AccountSelectionViewModel
import com.readrops.app.compose.home.HomeScreen import com.readrops.app.compose.home.HomeScreen
@ -15,7 +14,6 @@ import org.koin.androidx.viewmodel.ext.android.getViewModel
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
@OptIn(ExperimentalAnimationApi::class)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -25,7 +23,11 @@ class MainActivity : ComponentActivity() {
setContent { setContent {
ReadropsTheme { ReadropsTheme {
Navigator( Navigator(
screen = if (accountExists) HomeScreen() else AccountSelectionScreen() screen = if (accountExists) HomeScreen() else AccountSelectionScreen(),
disposeBehavior = NavigatorDisposeBehavior(
// prevent screenModels being recreated when opening a screen from a tab
disposeNestedNavigators = false
)
) { ) {
CurrentScreen() CurrentScreen()
} }

View File

@ -28,7 +28,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import cafe.adriel.voyager.koin.getNavigatorScreenModel import cafe.adriel.voyager.koin.getScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import cafe.adriel.voyager.navigator.tab.Tab import cafe.adriel.voyager.navigator.tab.Tab
@ -56,7 +56,7 @@ object AccountTab : Tab {
@Composable @Composable
override fun Content() { override fun Content() {
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
val viewModel = navigator.getNavigatorScreenModel<AccountScreenModel>() val viewModel = getScreenModel<AccountScreenModel>()
val closeHome by viewModel.closeHome.collectAsStateWithLifecycle() val closeHome by viewModel.closeHome.collectAsStateWithLifecycle()
val state by viewModel.accountState.collectAsStateWithLifecycle() val state by viewModel.accountState.collectAsStateWithLifecycle()

View File

@ -30,9 +30,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import cafe.adriel.voyager.koin.getNavigatorScreenModel import cafe.adriel.voyager.koin.getScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import cafe.adriel.voyager.navigator.tab.Tab import cafe.adriel.voyager.navigator.tab.Tab
import cafe.adriel.voyager.navigator.tab.TabOptions import cafe.adriel.voyager.navigator.tab.TabOptions
import com.readrops.app.compose.R import com.readrops.app.compose.R
@ -62,8 +60,7 @@ object FeedTab : Tab {
val haptic = LocalHapticFeedback.current val haptic = LocalHapticFeedback.current
val uriHandler = LocalUriHandler.current val uriHandler = LocalUriHandler.current
val navigator = LocalNavigator.currentOrThrow val viewModel = getScreenModel<FeedScreenModel>()
val viewModel = navigator.getNavigatorScreenModel<FeedScreenModel>()
val state by viewModel.feedsState.collectAsStateWithLifecycle() val state by viewModel.feedsState.collectAsStateWithLifecycle()

View File

@ -39,7 +39,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.paging.LoadState import androidx.paging.LoadState
import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.collectAsLazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems
import cafe.adriel.voyager.koin.getNavigatorScreenModel import cafe.adriel.voyager.koin.getScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import cafe.adriel.voyager.navigator.tab.Tab import cafe.adriel.voyager.navigator.tab.Tab
@ -69,7 +69,7 @@ object TimelineTab : Tab {
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
val context = LocalContext.current val context = LocalContext.current
val viewModel = navigator.getNavigatorScreenModel<TimelineScreenModel>() val viewModel = getScreenModel<TimelineScreenModel>()
val state by viewModel.timelineState.collectAsStateWithLifecycle() val state by viewModel.timelineState.collectAsStateWithLifecycle()
val items = state.itemState.collectAsLazyPagingItems() val items = state.itemState.collectAsLazyPagingItems()