Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Practical Tips and Tricks to Improve Your Compo...

Practical Tips and Tricks to Improve Your Compose Previews (Droidcon Lisbon 2025)

Jetpack Compose Preview is a powerful tool that provides real-time feedback on how our composables are rendered and even on how they behave and animate in certain conditions. While writing useful previews seems like a straightforward task, there are some things that we need to keep in mind. Preview code won't reach users of your app (hopefully!); however, it's more likely that the author of the preview and future peers as well might have to work with them eventually.

This talk will touch on the following topics:
- Recap on the main features and limitations of Compose previews
- How we can overcome the limitations of @Preview being an annotation
- How we can make our previews developer-friendly
- What we can use our previews for besides checking how our composables are rendered and how they behave

Avatar for István Juhos

István Juhos

September 05, 2025
Tweet

More Decks by István Juhos

Other Decks in Programming

Transcript

  1. @Preview(device = "spec:width=960dp,height=1080dp,dpi=480") @Composable private fun TitleSlidePreview() { PreviewBox {

    TitleSlide() } } @Composable private fun TitleSlide() { Column( modifier = Modifier .fillMaxSize() .paint( painter = painterResource( id = R.drawable.glenn_carstens_peters, ), contentScale = ContentScale.FillBounds, ) .padding(32.dp) ) { Title( modifier = Modifier .fillMaxWidth() .padding(top = 32.dp), fontSize = 70.sp, ) Column( horizontalAlignment = CenterHorizontally, modifier = Modifier .fillMaxWidth() ) { Name( modifier = Modifier .weight(1f) .padding(bottom = 66.dp), imageHeight = 66.dp, textSize = 70.sp, ) Contacts( modifier = Modifier .padding( bottom = 16.dp, end = 16.dp, ), fontSize = 50.sp, ) } } } Practical Tips and Tricks to Improve Your Compose Previews István Juhos @istvanjuhos.dev
  2. @istvanjuhos.dev #dclx25 @Preview @Composable private fun PreviewListItem() { AppTheme {

    ListItem( text = "List item", onClick = {}, ) } } Compose preview
  3. @istvanjuhos.dev #dclx25 @Preview @Composable private fun PreviewListItem() { AppTheme {

    ListItem( text = "List item", onClick = {}, ) } } Compose preview
  4. @istvanjuhos.dev #dclx25 @Preview @Composable private fun PreviewListItem() { AppTheme {

    ListItem( text = "List item", onClick = {}, ) } } • Code Compose preview
  5. @istvanjuhos.dev #dclx25 • Code, that • will never reach production

    @Preview @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } } Compose preview
  6. @istvanjuhos.dev #dclx25 • Code, that • will never reach productio

    n​ … 🤞 @Preview @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } } Compose preview
  7. @istvanjuhos.dev #dclx25 • Code, that • will never reach production…

    • others will read 🤞 @Preview @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } } Compose preview
  8. @istvanjuhos.dev #dclx25 • Code, that • will never reach production…

    • others will read • needs to be maintained 🤞 @Preview @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } } Compose preview
  9. @istvanjuhos.dev #dclx25 • Code, that • will never reach production…

    • others will read • needs to be maintained • communicates via tooling 🤞 @Preview @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } } Compose preview
  10. @istvanjuhos.dev #dclx25 Consider IDE themes @Composable fun ListItem( text: String,

    onClick: () -> Unit, modifier: Modifier = Modifier, ) { Row( verticalAlignment = Alignment.CenterVertically, modifier = modifier .clickable(onClick = onClick) .padding(16.dp), ) { Text( text = text, style = PreviewTheme.typography.bodyMedium, color = PreviewTheme.colors.text, modifier = Modifier.weight(1f), ) Image( imageVector = KeyboardArrowRight, contentDescription = null, colorFilter = ColorFilter.tint(PreviewTheme.colors.text) ) } }
  11. Consider IDE themes • Render Composable functions annotated with @Preview

    @Composable fun ListItem( text: String, onClick: () -> Unit, modifier: Modifier = Modifier, ) { Row( verticalAlignment = Alignment.CenterVertically, modifier = modifier .clickable(onClick = onClick) .padding(16.dp), ) { Text( text = text, style = PreviewTheme.typography.bodyMedium, color = PreviewTheme.colors.text, modifier = Modifier.weight(1f), ) Image( imageVector = KeyboardArrowRight, contentDescription = null, colorFilter = ColorFilter.tint(PreviewTheme.colors.text) ) } }
  12. Consider IDE themes • Render Composable functions annotated with @Preview

    @Composable fun ListItem( text: String, onClick: () -> Unit, modifier: Modifier = Modifier, ) { Row( verticalAlignment = Alignment.CenterVertically, modifier = modifier .clickable(onClick = onClick) .padding(16.dp), ) { Text( text = text, style = PreviewTheme.typography.bodyMedium, color = PreviewTheme.colors.text,
  13. Consider IDE themes • Render Composable functions annotated with @Preview

    @Composable fun ListItem( text: String, onClick: () -> Unit, modifier: Modifier = Modifier, ) { Row( verticalAlignment = Alignment.CenterVertically, modifier = modifier .clickable(onClick = onClick) .padding(16.dp), ) { Text( text = text, style = PreviewTheme.typography.bodyMedium, color = PreviewTheme.colors.text,
  14. @istvanjuhos.dev #dclx25 Consider IDE themes @Preview @Composable private fun PreviewListItem()

    { AppTheme { ListItem( text = "List item", onClick = {}, ) } }
  15. @istvanjuhos.dev #dclx25 Consider IDE themes @Preview @Composable private fun PreviewListItem()

    { AppTheme { ListItem( text = "List item", onClick = {}, ) } }
  16. @istvanjuhos.dev #dclx25 Consider IDE themes @Preview @Composable private fun PreviewListItem()

    { AppTheme { ListItem( text = "List item", onClick = {}, ) } }
  17. @istvanjuhos.dev #dclx25 @Preview @Composable private fun PreviewListItem() { AppTheme {

    ListItem( text = "List item", onClick = {}, ) } } Consider IDE themes
  18. @istvanjuhos.dev #dclx25 @Preview @Composable private fun PreviewListItem() { AppTheme {

    ListItem( text = "List item", onClick = {}, ) } } Consider IDE themes
  19. @istvanjuhos.dev #dclx25 @Preview @Composable private fun PreviewListItem() { AppTheme {

    ListItem( text = "List item", onClick = {}, ) } } Consider IDE themes
  20. @istvanjuhos.dev #dclx25 @Preview( showBackground = true, ) @Composable private fun

    PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } } Consider IDE themes
  21. @istvanjuhos.dev #dclx25 @Preview( showBackground = true, ) @Composable private fun

    PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } } Consider IDE themes vs
  22. @istvanjuhos.dev #dclx25 @Preview( showBackground = true, ) @Composable private fun

    PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } } Use annotation parameters
  23. @istvanjuhos.dev #dclx25 @Preview( showBackground = true, ) @Composable private fun

    PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } } Use annotation parameters
  24. @istvanjuhos.dev #dclx25 @Preview( showBackground = true, backgroundColor = 0xFF_E7ECF4, )

    @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } } Use annotation parameters
  25. @istvanjuhos.dev #dclx25 @Preview( showBackground = true, backgroundColor = 0xFF_E7ECF4, //

    gray.w500 ) @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } } Use annotation parameters
  26. @istvanjuhos.dev #dclx25 Use annotation parameters @Preview( showBackground = true, backgroundColor

    = GRAY_W500, ) @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } } const val GRAY_W500 = 0xFF_E7ECF4 ...
  27. @istvanjuhos.dev #dclx25 Use annotation parameters @Preview( showBackground = true, backgroundColor

    = GRAY_W500, ) @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } }
  28. @istvanjuhos.dev #dclx25 Use annotation parameters @Preview( showBackground = true, backgroundColor

    = GRAY_W500, uiMode = Configuration.UI_MODE_NIGHT_YES, ) @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } }
  29. @istvanjuhos.dev #dclx25 Use annotation parameters @Preview( showBackground = true, backgroundColor

    = GRAY_W500, ) @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, ) } }
  30. @istvanjuhos.dev #dclx25 Use annotation parameters @Preview( showBackground = true, backgroundColor

    = GRAY_W500, ) @Preview( showBackground = true, backgroundColor = GRAY_W500, ) @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, )
  31. @istvanjuhos.dev #dclx25 Use annotation parameters @Preview( showBackground = true, backgroundColor

    = GRAY_W500, ) @Preview( showBackground = true, backgroundColor = DARK_GRAY_W500, ) @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {}, )
  32. @istvanjuhos.dev #dclx25 Use annotation parameters @Preview( showBackground = true, backgroundColor

    = GRAY_W500, ) @Preview( showBackground = true, backgroundColor = DARK_GRAY_W500, uiMode = Configuration.UI_MODE_NIGHT_YES, ) @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {},
  33. @istvanjuhos.dev #dclx25 Use annotation parameters @Preview( showBackground = true, backgroundColor

    = GRAY_W500, ) @Preview( showBackground = true, backgroundColor = DARK_GRAY_W500, uiMode = Configuration.UI_MODE_NIGHT_YES, ) @Composable private fun PreviewListItem() { AppTheme { ListItem( text = "List item", onClick = {},
  34. @istvanjuhos.dev #dclx25 Preview annotation parameters android x​ .compose.ui.tooling.preview org.jetbrain s​

    .compose.ui.tooling.preview @Preview( name = "", group = "", widthDp = 360, heightDp = 640, locale = "pt_PT", showBackground = true, backgroundColor = 0xFFFFFF, showSystemUi = true, apiLevel = 35, fontScale = 1f, uiMode = UI_MODE_NIGHT_YES, device = PIXEL_9_PRO_FOLD, wallpaper = GREEN_DOMINATED_EXAMPLE, ) @Preview( name = "", group = "", widthDp = 360, heightDp = 640, locale = "pt_PT", showBackground = true, backgroundColor = 0xFFFFFF )
  35. @istvanjuhos.dev #dclx25 Preview annotation parameters android x​ .compose.ui.tooling.preview org.jetbrain s​

    .compose.ui.tooling.preview @Preview( name = "", group = "", widthDp = 360, heightDp = 640, locale = "pt_PT", showBackground = true, backgroundColor = 0xFFFFFF, showSystemUi = true, apiLevel = 35, fontScale = 1f, uiMode = UI_MODE_NIGHT_YES, device = PIXEL_9_PRO_FOLD, wallpaper = GREEN_DOMINATED_EXAMPLE, ) @Preview( name = "", group = "", widthDp = 360, heightDp = 640, locale = "pt_PT", showBackground = true, backgroundColor = 0xFFFFFF )
  36. @istvanjuhos.dev #dclx25 Preview annotation parameters android x​ .compose.ui.tooling.preview org.jetbrain s​

    .compose.ui.tooling.preview @Preview( name = "", group = "", widthDp = 360, heightDp = 640, locale = "pt_PT", showBackground = true, backgroundColor = 0xFFFFFF, showSystemUi = true, apiLevel = 35, fontScale = 1f, uiMode = UI_MODE_NIGHT_YES, device = PIXEL_9_PRO_FOLD, wallpaper = GREEN_DOMINATED_EXAMPLE, ) @Preview( name = "", group = "", widthDp = 360, heightDp = 640, locale = "pt_PT", showBackground = true, backgroundColor = 0xFFFFFF )
  37. @istvanjuhos.dev #dclx25 @Preview( ... ) @Preview( ... ) @Composable private

    fun PreviewListItem() { ... } Name your previews
  38. @istvanjuhos.dev #dclx25 @Preview( name = "Light - Primary", ... )

    @Preview( name = "Dark - Primary", ... ) @Composable private fun PreviewListItem() { ... } Name your previews
  39. @istvanjuhos.dev #dclx25 @Preview( name = "Light - Secondary", ... )

    @Preview( name = "Dark - Secondary", ... ) @Composable private fun PreviewListItem() { ... } Name your previews
  40. @istvanjuhos.dev #dclx25 @Preview( ... ) @Preview( ... ) @Preview( ...

    ) @Preview( ... ) @Composable private fun PreviewListItem() { ... } Name your previews
  41. @istvanjuhos.dev #dclx25 @Preview( name = "Light - Primary", group =

    "Light/Dark - Primary", ... ) @Preview( name = "Dark - Primary", group = "Light/Dark - Primary”, ... ) @Composable private fun PreviewListItem() { ... } Group your previews
  42. @istvanjuhos.dev #dclx25 @Preview( name = "Light - Secondary", group =

    "Light/Dark - Secondary", ... ) @Preview( name = "Dark - Secondary", group = "Light/Dark - Secondary", ... ) @Composable private fun PreviewListItem() { ... } Group your previews
  43. @istvanjuhos.dev #dclx25 @Preview( ... ) @Preview( ... ) @Preview( ...

    ) @Preview( ... ) @Composable private fun PreviewListItem() { ... } Group your previews
  44. @istvanjuhos.dev #dclx25 @Preview( ... ) @Preview( ... ) @Preview( ...

    ) @Preview( ... ) @Composable private fun PreviewListItem() { ... } Group your previews
  45. @istvanjuhos.dev #dclx25 @Preview( ... ) @Preview( ... ) @Preview( ...

    ) @Preview( ... ) @Composable private fun PreviewListItem() { ... } Create multipreviews
  46. @Preview( name = "Light - Primary", group = "Light/Dark -

    Primary", showBackground = true, backgroundColor = GRAY_W500, ) @Preview( name = "Dark - Primary", group = "Light/Dark - Primary", showBackground = true, backgroundColor = DARK_GRAY_W500, uiMode = UI_MODE_NIGHT_YES, ) annotation class PreviewPrimaryBackground Create multipreviews
  47. @Preview( name = "Light - Secondary", group = "Light/Dark -

    Secondary", showBackground = true, backgroundColor = GRAY_W100, ) @Preview( name = "Dark - Secondary", group = "Light/Dark - Secondary", showBackground = true, backgroundColor = DARK_GRAY_W100, uiMode = UI_MODE_NIGHT_YES, ) annotation class PreviewSecondaryBackground Create multipreviews
  48. @Preview( name = "Light - Secondary", group = "Light/Dark -

    Secondary", showBackground = true, backgroundColor = GRAY_W100, ) @Preview( name = "Dark - Secondary", group = "Light/Dark - Secondary", showBackground = true, backgroundColor = DARK_GRAY_W100, uiMode = UI_MODE_NIGHT_YES, ) annotation class PreviewSecondaryBackground Create multipreviews
  49. @istvanjuhos.dev #dclx25 @Composable private fun PreviewListItem() { AppTheme { ListItem(

    text = "List item", onClick = {}, ) } } Create multipreviews @PreviewPrimaryBackground @PreviewSecondaryBackground annotation class PreviewAllBackgrounds
  50. @istvanjuhos.dev #dclx25 @PreviewAllBackgrounds @Composable private fun PreviewListItem() { AppTheme {

    ListItem( text = "List item", onClick = {}, ) } } Create multipreviews @PreviewPrimaryBackground @PreviewSecondaryBackground annotation class PreviewAllBackgrounds
  51. @istvanjuhos.dev #dclx25 Multipreview templates androidx.compose.ui.tooling.preview @PreviewLightDark @PreviewFontScale @Previe w​ ScreenSizes

    @PreviewDynamicColors ✅ developer.android.com/develop/ui/compose/tooling/previews#multipreview-templates
  52. @istvanjuhos.dev #dclx25 Multipreview support with CMP org.jetbrain s​ .compose.ui.tooling.preview @Preview(

    name = "Example preview name", group = "Example preview group", showBackground = true, backgroundColor = GRAY_W500, widthDp = 1080, heightDp = 1920, locale = "pt_PT", ) CMP 1.9-beta01+
  53. @istvanjuhos.dev #dclx25 Multipreview support with CMP org.jetbrain s​ .compose.ui.tooling.preview @Preview(

    name = "Example preview name", group = "Example preview group", showBackground = true, backgroundColor = GRAY_W500, widthDp = 1080, heightDp = 1920, locale = "pt_PT", ) CMP 1.9-beta01+
  54. @istvanjuhos.dev #dclx25 Multipreview support with CMP org.jetbrain s​ .compose.ui.tooling.preview @Preview(

    name = "Example preview name", group = "Example preview group", showBackground = true, backgroundColor = GRAY_W500, widthDp = 1080, heightDp = 1920, locale = "pt_PT", ) CMP 1.9-beta01+
  55. @istvanjuhos.dev #dclx25 Multipreview examples - MultiThemePreview @Preview( name = "Dark

    mode", group = "Theme", uiMode = Configuration .UI_MODE_NIGHT_YES ) @Preview( name = "Default", group = "Theme", ) annotation class MultiThemePreview
  56. @istvanjuhos.dev #dclx25 Multipreview examples - MultiLocationPreview @Preview( name = "Greek",

    group = "Locale", locale = "el", ) ... @Preview( name = "Portuguese", group = "Locale", locale = "pt", ) @Preview( name = "Arabic", group = "Locale", locale = "ar", ) @Preview( name = "(Default locale)", group = "Locale", ) annotation class MultiLocalePreview
  57. @istvanjuhos.dev #dclx25 @PreviewLightDark @Composable private fun PrimaryButtonPreview() { AppTheme {

    PrimaryButton( text = "Primary Button", leadingIcon = R.drawable.ic_add, onClick = {}, ) } } Let’s build our preview
  58. @istvanjuhos.dev #dclx25 @Composable fun PreviewBox( modifier: Modifier = Modifier, content:

    @Composable () -> Unit, ) { AppTheme { content() } } Building preview tools
  59. @istvanjuhos.dev #dclx25 @Composable fun PreviewBox( modifier: Modifier = Modifier, content:

    @Composable () -> Unit, ) { AppTheme { Box { content() } } } Building preview tools
  60. @istvanjuhos.dev #dclx25 @Composable fun PreviewBox( modifier: Modifier = Modifier, backgroundColor:

    @Composable () -> Color = content: @Composable () -> Unit, ) { AppTheme { Box( modifier = modifier .background(backgroundColor()), ) { content() } } } Building preview tools
  61. @istvanjuhos.dev #dclx25 @Composable fun PreviewBox( modifier: Modifier = Modifier, backgroundColor:

    @Composable () -> Color = { AppTheme.colors.backgroundSecondary }, content: @Composable () -> Unit, ) { AppTheme { Box( modifier = modifier .background(backgroundColor()), ) { content() } } } Building preview tools
  62. @istvanjuhos.dev #dclx25 @Composable fun PreviewBox( modifier: Modifier = Modifier, backgroundColor:

    @Composable () -> Color = { AppTheme.colors.backgroundSecondary }, content: @Composable () -> Unit, ) { AppTheme { Box( modifier = modifier .background(backgroundColor()), ) { content() } } } Building preview tools
  63. @istvanjuhos.dev #dclx25 @Composable fun PreviewBox( modifier: Modifier = Modifier, backgroundColor:

    @Composable () -> Color = { AppTheme.colors.backgroundSecondary }, content: @Composable () -> Unit, ) { AppTheme { Box( ... ) { content() } } } Building preview tools
  64. @istvanjuhos.dev #dclx25 @Composable fun PreviewBox( modifier: Modifier = Modifier, backgroundColor:

    @Composable () -> Color = { AppTheme.colors.backgroundSecondary }, paddingValues: PaddingValues = PaddingValues(4.dp), content: @Composable () -> Unit, ) { AppTheme { Box( ... ) { content() } } } Building preview tools
  65. @istvanjuhos.dev #dclx25 @Composable fun Previe w​ Box( ... content: @Composable

    () -> Unit, ) { AppTheme { Box( ... ) { content() } } } Building preview tools
  66. @istvanjuhos.dev #dclx25 @Composable fun Previe w​ Column( ... content: @Composable

    () -> Unit, ) { AppTheme { Column( ... ) { content() } } } Building preview tools
  67. @istvanjuhos.dev #dclx25 @Composable fun PreviewDialog( modifier: Modifier = Modifier, factory:

    (context: Context) -> Dialog, ) { PreviewBox( contentPadding = PaddingValues(), ) { AndroidView( modifier = modifier, factory = { context -> val dialog = factory(context) dialog.create() val view = dialog.findViewById<View>(android.R.id.content) (view.parent as ViewGroup).removeView(view) view }, ) } } Building preview tools
  68. @istvanjuhos.dev #dclx25 @Composable fun PreviewDialog( modifier: Modifier = Modifier, factory:

    (context: Context) -> Dialog, ) { PreviewBox( contentPadding = PaddingValues(), ) { AndroidView( modifier = modifier, factory = { context -> val dialog = factory(context) dialog.create() val view = dialog.findViewById<View>(android.R.id.content) (view.parent as ViewGroup).removeView(view) view }, ) } } Building preview tools
  69. @istvanjuhos.dev #dclx25 Override CompositionLocals @Composable fun PreviewColumn( ... layoutDirection: LayoutDirection

    = LayoutDirection.Ltr, content: @Composable () -> Unit, ) { AppTheme { Column( ... ) { content() } } }
  70. @istvanjuhos.dev #dclx25 Override CompositionLocals @Composable fun PreviewColumn( ... layoutDirection: LayoutDirection

    = LayoutDirection.Ltr, content: @Composable () -> Unit, ) { CompositionLocalProvider( LocalLayoutDirection provides layoutDirection, ) { AppTheme { Column( ... ) { content() } } } }
  71. @istvanjuhos.dev #dclx25 Override CompositionLocals @PreviewLightDark @Composable private fun PreviewColumnPreview() {

    PreviewColumn( layoutDirection = LayoutDirection.Ltr, ) { PrimaryButton( ... ) ListItem( ... ) } }
  72. @istvanjuhos.dev #dclx25 Override CompositionLocals @PreviewLightDark @Composable private fun PreviewColumnPreview() {

    PreviewColumn( layoutDirection = LayoutDirection.Rtl, ) { PrimaryButton( ... ) ListItem( ... ) } }
  73. @istvanjuhos.dev #dclx25 Override CompositionLocals @PreviewLightDark @Composable private fun PreviewColumnPreview() {

    PreviewColumn( layoutDirection = LayoutDirection.Rtl, ) { PrimaryButton( .. . ) ListItem( .. . ) } }
  74. @istvanjuhos.dev #dclx25 Override CompositionLocals @PreviewLightDark @Composable private fun PreviewColumnPreview() {

    PreviewColumn( layoutDirection = LayoutDirection.Rtl, ) { PrimaryButton( .. . ) ListItem( .. . ) } }
  75. @istvanjuhos.dev #dclx25 Override CompositionLocals @PreviewLightDark @Composable private fun PreviewColumnPreview() {

    PreviewColumn( layoutDirection = LayoutDirection.Rtl, ) { PrimaryButton( .. . ) ListItem( .. . ) } }
  76. @istvanjuhos.dev #dclx25 Make previews interactive @Composable fun FloatingPinMapOverlay( isLifted: Boolean,

    modifier: Modifier = Modifier, ) { /* Some beautifully animated content */ }
  77. @istvanjuhos.dev #dclx25 Make previews interactive @Composable fun FloatingPinMapOverlay( isLifted: Boolean,

    modifier: Modifier = Modifier, ) { /* Some beautifully animated content */ }
  78. @istvanjuhos.dev #dclx25 Make previews interactive @Composable fun FloatingPinMapOverlay( isLifted: Boolean,

    modifier: Modifier = Modifier, ) { /* Some beautifully animated content */ }
  79. @istvanjuhos.dev #dclx25 Make previews interactive @Composable fun FloatingPinMapOverlay( isLifted: Boolean,

    modifier: Modifier = Modifier, ) { /* Some beautifully animated content */ } @Preview @Composable private fun PreviewFloatingPinMapOverlay() { var isLifted by remember { mutableStateOf(false) } PreviewBox( . .. modifier = Modifier.clickable { isLifted = !isLifted }, ) { FloatingPinMapOverlay( isLifted = isLifted, ) } }
  80. @istvanjuhos.dev #dclx25 Make previews interactive @Composable fun FloatingPinMapOverlay( isLifted: Boolean,

    modifier: Modifier = Modifier, ) { /* Some beautifully animated content */ } @Preview @Composable private fun PreviewFloatingPinMapOverlay() { var isLifted by remember { mutableStateOf(false) } PreviewBox( . .. modifier = Modifier.clickable { isLifted = !isLifted }, ) { FloatingPinMapOverlay( isLifted = isLifted, ) } }
  81. @istvanjuhos.dev #dclx25 Make previews interactive @Composable fun FloatingPinMapOverlay( isLifted: Boolean,

    modifier: Modifier = Modifier, ) { /* Some beautifully animated content */ } @Preview @Composable private fun PreviewFloatingPinMapOverlay() { var isLifted by remember { mutableStateOf(false) } PreviewBox( . .. modifier = Modifier.clickable { isLifted = !isLifted }, ) { FloatingPinMapOverlay( isLifted = isLifted, ) } }
  82. @istvanjuhos.dev #dclx25 Make previews interactive @Composable fun FloatingPinMapOverlay( isLifted: Boolean,

    modifier: Modifier = Modifier, ) { /* Some beautifully animated content */ } @Preview @Composable private fun PreviewFloatingPinMapOverlay() { var isLifted by remember { mutableStateOf(false) } PreviewBox( . .. modifier = Modifier.clickable { isLifted = !isLifted }, ) { FloatingPinMapOverlay( isLifted = isLifted, ) } }
  83. @istvanjuhos.dev #dclx25 Make previews interactive @Composable fun FloatingPinMapOverlay( isLifted: Boolean,

    modifier: Modifier = Modifier, ) { /* Some beautifully animated content */ } @Preview @Composable private fun PreviewFloatingPinMapOverlay() { var isLifted by remember { mutableStateOf(false) } PreviewBox( . .. modifier = Modifier.clickable { isLifted = !isLifted }, ) { FloatingPinMapOverlay( isLifted = isLifted, ) } }
  84. @istvanjuhos.dev #dclx25 Some more ideas • Use previews for screenshot

    testing github.com/sergio-sastre/ComposablePreviewScanner
  85. @istvanjuhos.dev #dclx25 Some more ideas • … make the whole

    app runnable in Preview 🤷 medium.com/whatnot-engineering/preview-driven-development-with-compose-f7a5beee95aa
  86. Practical Tips and Tricks to Improve Your Compose Previews •

    Think of Previews as a form of communication • Create at least one Preview per unit of UI • Compose reusable tools to ease Preview development istvanjuhos.dev István Juhos Photo by Glenn Carstens-Peters