Can we or should use Preview compose function for main widget as well?

683 views Asked by At

Like below are two functions

@Composable
private fun WaterCounter(modifier: Modifier = Modifier) {
    val count = 0
    Text(
        text = "You've had $count glasses of water",
        modifier = modifier.padding(all = 16.dp)
    )
}

@Preview(showBackground = true)
@Composable
private fun PreviewWaterCounter() {
    WaterCounter()
}

So, wouldn't it be better if we add @Preview annotation to the WaterCounter, which will save some lines of code and will work both as a preview and a widget?

1

There are 1 answers

0
z.g.y On BEST ANSWER

For simple situations like your posted code, having a separate composable preview seems a bit too much, but consider this scenario with 2 composables with non-default parameters,

@Composable
fun PersonBiography(
    details: Data,
    otherParameters : Any?
) {
    Box(
        modifier = Modifier.background(Color.Red)
    ) {
        Text(details.dataValue)
    }
}

@Composable
fun AccountDetails(
    details: Data
) {
    Box(
        modifier = Modifier.background(Color.Green)
    ) {
        Text(details.dataValue)
    } 
}

both of them requires same data class , the first one has an additional parameter. If I have to preview them I have to break their signature, assigning default values to them just for the sake of the preview.

@Preview
@Composable
fun PersonBiography(
    details: Data = Data(dataValue = ""),
    otherParameters : Any? = null
) { … }

@Preview
@Composable
fun AccountDetails(
    details: Data = Data(dataValue = "")
) { … }

A good workaround on this is having 2 separate preview composables and taking advantage of PreviewParameterProvider to have a re-usable utility that can provide instances of the parameters I needed.

class DetailsPreviewProvider : PreviewParameterProvider<Data> {
    override val values = listOf(Data(dataValue = "Some Data")).asSequence()
}

@Preview
@Composable
fun PersonBiographyPreview(@PreviewParameter(DetailsPreviewProvider::class) details: Data) {
    PersonBiography(
        details = details,
        // you may also consider creating a separate provider for this one if needed
        null
    )
}

@Preview
@Composable
fun AccountDetailsPreview(@PreviewParameter(DetailsPreviewProvider::class) details: Data) {
    AccountDetails(details)
}

enter image description here

Or if PreviewParameterProvider is a bit too much, you can simply create a preview composable where you can create and supply the mock data.

@Preview
@Composable
fun AccountDetailsPreview() {
    val data = Data("Some Account Information")
    AccountDetails(data)
}

enter image description here

With any of these approaches, you don't need to break your actual composable's structure just to have a glimpse of what it would look like.