Reputation: 167
I am discovering android Jetpack Compose (and Navigation) and try to display a preview of a view with a navController
as parameter.
To achieve this, I use the PreviewParameter
and I have no error, but nothing is displayed in the Preview window.
Does anyone know how pass a fake NavController
instance to a Composable?
class FakeNavController : PreviewParameterProvider<NavController> {
override val values: Sequence<NavController>
get() {}
}
@Preview
@Composable
fun Preview(
@PreviewParameter(FakeNavController::class) fakeNavController: NavController
) {
HomeView(fakeNavController)
}
Upvotes: 16
Views: 11213
Reputation: 31
That happens due to the limitations of jetpack compose when dealing with external libraries, but there is a solution that I tried: 1-Don't pass navController to the screen, instead pass a funtion type( onMoveButtonClick:()->Unit ) for the screen that you have. 2-In the navGraph you specify what should happen when clicking the button like this:
HomeView(
onMoveButtonClick={
navController.navigate(...)
}
)
in the preview pass empty lambda like this
@Preview
@Composable
fun Preview(){
HomeView(onMoveButtonClick={})
}
for more help send me here: [email protected]
Upvotes: 0
Reputation: 715
You don't have to make it nullable and pass null to it.
You just need to pass this: rememberNavController()
@Preview
@Composable
fun Preview() {
HomeView(rememberNavController())
}
Upvotes: 46
Reputation: 167
Finally, I declare a nullable NavController and it works.
@Composable
fun HomeView(navController: NavController?) {
Surface {
Column(
modifier = Modifier
.padding(all = 4.dp)
) {
Text(
text = "Home View",
style = MaterialTheme.typography.body2
)
Spacer(modifier = Modifier.height(8.dp))
Button(onClick = { navController?.navigate("lineRoute") }) {
Text(text = "nav to Line view")
}
}
}
}
@Preview
@Composable
fun Preview (){
HomeView(null)
}
Upvotes: -1
Reputation: 88132
PreviewParameter
is used to create multiple previews of the same view with different data. You're expected to return the needed values from values
. In your example you return nothing that's why it doesn't work(it doesn't even build in my case).
That won't help you to mock the navigation controller, as you still need to create it somehow to return from values
. I think it's impossible.
Instead you can pass a handler, in this case you don't need to mock it:
@Composable
fun HomeView(openOtherScreen: () -> Unit) {
}
// your Navigation view
composable(Destinations.Home) { from ->
HomeView(
openOtherScreen = {
navController.navigate(Destinations.Other)
},
)
}
Upvotes: 6