Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with @Preview annotation at child composables [Compose Navigation] #2

Closed
glush opened this issue Sep 27, 2021 · 1 comment
Closed

Comments

@glush
Copy link

glush commented Sep 27, 2021

Let say. I have something like like:

Navigation

  • Screen1
  • Screen2 {
    .....
    Composable20
    ....
    Composable21
    }

When I'm making @Preview for child composable AS can't render preview for this composable and show render error with exception like:

java.lang.IllegalStateException: Current Composable is not wrapped in KoinNavigation
at dev.burnoo.cokoin.navigation.NavigationKt$LocalNavController$1.invoke(Navigation.kt:23)
at dev.burnoo.cokoin.navigation.NavigationKt$LocalNavController$1.invoke(Navigation.kt:22)
at layoutlib.internal.kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at androidx.compose.runtime.LazyValueHolder.getCurrent(ValueHolders.kt:29)
at androidx.compose.runtime.LazyValueHolder.getValue(ValueHolders.kt:31)
at androidx.compose.runtime.ComposerImpl.resolveCompositionLocal(Composer.kt:1774)
at androidx.compose.runtime.ComposerImpl.consume(Composer.kt:1744)
at dev.burnoo.cokoin.navigation.NavigationKt.getNavController(Navigation.kt:82)

I can build app and it run w/o problem. So it just AS @Preview problem.

@burnoo
Copy link
Owner

burnoo commented Sep 28, 2021

Jetpack Compose doesn't support creating ViewModels in @Preview. You can read more about it here: https://stackoverflow.com/questions/64841794/viewmodels-creation-is-not-supported-in-preview

Although there are two possible ways of getting previews when you use ViewModels.

1. Don't use getViewModel in @Preview:

@Composable
fun App() {
    val navController = rememberNavController()
    KoinNavHost(navController, startDestination = "1") {
        composable("1") {
             val viewModel = getNavViewModel<MainViewModel>()
             Screen1(viewModel.state, viewModel::onClick)
        }
    }
}

@Preview
@Composable
fun Screen1(state: UiState = PreviewState, onClick: () -> Unit = {}) {
    // ...
}

2. Create ViewModel manually for @Preview

// reusable helper
@Composable
fun KoinNavPreview(content: @Composable () -> Unit) {
    Koin(appDeclaration = { modules(previewModule) }) {
        KoinNav(navController = rememberNavController()) {
            content()
        }
    }
}

@Composable
fun Screen1(viewModel: NavViewModel = getNavViewModel()) {
    val navController = getNavController()
    Button(onClick = { navController.navigate("2") }) {
        Text(viewModel.id.toString())
    }
}

@Preview
@Composable
fun Screen1Preview() {
    KoinNavPreview {
        Screen1(viewModel = NavViewModel(data = "previewData"))
    }
}

@burnoo burnoo closed this as completed Dec 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants