Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Compose Previews as a Power User
Search
Subhrajyoti Sen
October 06, 2024
Programming
250
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Compose Previews as a Power User
Subhrajyoti Sen
October 06, 2024
More Decks by Subhrajyoti Sen
See All by Subhrajyoti Sen
Understanding Incremental Processing in the JVM World
subhrajyotisen
0
63
Updated Lessons from a KMP Developer's Toolkit
subhrajyotisen
0
80
Building Mobile Apps and Scaling them
subhrajyotisen
0
80
Understanding WindowInsets
subhrajyotisen
0
280
Exploring a KMM Developer’s Toolkit
subhrajyotisen
1
290
Shipping Apps Confidently with Firebase
subhrajyotisen
0
150
Understanding WindowInsets - Android Worldwide
subhrajyotisen
0
410
Understanding WindowInsets
subhrajyotisen
1
250
Demystifying Styles and Themes
subhrajyotisen
0
300
Other Decks in Programming
See All in Programming
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
910
Java 27新機能 / Java 27 new features
kishida
2
200
Heart of Swift Concurrency
koher
0
1.2k
Agents on Rails - Rails at Scale 2026
irinanazarova
0
340
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
110
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
540
JAWS-UG 東京支部が始める、JAWS-UG支部コラボ / JAWS-UG lunchtime LT Collaboration
y0hgi
0
190
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
390
ソニーのクラウド共通基盤の変遷とAI時代の開発スタイルに合わせた進化 / The Journey of Sony’s Common Cloud Platform and Its Evolution for AI-Native Development
kenjiyoneyama
0
230
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
140
カツオ、ご期待ください
suneo3476
0
150
残高管理から台帳サービスへの進化
artoy
0
160
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
450
Done Done
chrislema
187
17k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
570
Making the Leap to Tech Lead
cromwellryan
135
10k
Facilitating Awesome Meetings
lara
57
7.2k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Designing for humans not robots
tammielis
254
26k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Side Projects
sachag
456
43k
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Transcript
Compose Previews as a Power User Chennai Subhrajyoti Sen Motive
Simple Previews
@Composable fun BorrowedItemRowPreview() { BorrowedItemRow( item = BorrowItem( id =
0, itemName = "XBox Series X", borrowerName = "Steve", borrowDate = "2-11-2023" ) ) }
@Preview @Composable fun BorrowedItemRowPreview() { BorrowedItemRow( item = BorrowItem( id
= 0, itemName = "XBox Series X", borrowerName = "Steve", borrowDate = "2-11-2023" ) ) }
@Preview @Composable fun BorrowedItemRowPreview() { BorrowedItemRow( item = BorrowItem( id
= 0, itemName = "XBoz Series X", borrowerName = "Steve", borrowDate = "2-11-2023" ) ) }
None
Available Arguments • name • group • uiMode • locale
• showSystemUi • showBackground • device • apiLevel
Dark Mode
@Preview(uiMode = UI_MODE_NIGHT_YES) @Composable fun BorrowedItemRowDevicePreview() { BorrowTheme { BorrowedItemRow(
item = //.. ) } }
None
Multi Preview Annotation
@Preview(uiMode = UI_MODE_NIGHT_NO) @Preview(uiMode = UI_MODE_NIGHT_YES) @Composable fun BorrowedItemRowDevicePreview() {
BorrowTheme { BorrowedItemRow( item = //.. ) } }
@Preview(uiMode = UI_MODE_NIGHT_NO) @Preview(uiMode = UI_MODE_NIGHT_YES) annotation class LightDarkThemePreview
@LightDarkThemePreview @Composable fun BorrowedItemRowDevicePreview() { BorrowTheme { BorrowedItemRow( item =
//.. ) } }
@LightDarkThemePreview @Composable fun BorrowedItemRowDevicePreview() { BorrowTheme { BorrowedItemRow( item =
//.. ) } }
None
@Preview( showSystemUi = true, device = Devices.NEXUS_5X ) @Preview( showSystemUi
= true, device = Devices.NEXUS_10 ) annotation class MultiDevicePreview
@Preview( showSystemUi = true, device = Devices.NEXUS_5X ) @Preview( showSystemUi
= true, device = Devices.NEXUS_10 ) annotation class MultiDevicePreview
@Preview(locale = "en") @Preview(locale = "fr-rCA") @Preview(locale = "es-rUS") annotation
class MultiLocalePreview Valid locale format: https://developer.android.com/guide/topics/resources/provid ing-resources#LocaleQualifier
@LightDarkThemePreview @MultiLocalePreview annotation class MultiLocaleLightDarkPreview
Dataset Driven Preview
None
@Preview @Composable fun BorrowedItemRowPreview() { BorrowedItemRow( item = BorrowItem( id
= 0, itemName = "XBox Series X", borrowerName = "Steve", borrowDate = "2-11-2023" ) ) } @Preview @Composable fun BorrowedItemRowPreview() { BorrowedItemRow( item = BorrowItem( id = 0, itemName = "PlayStation", borrowerName = "Steve", borrowDate = "2-11-2023" ) ) }
class BorrowItemsProvider : PreviewParameterProvider<BorrowItem> { override val values = sequenceOf(
BorrowItem( id = 0, itemName = "PlayStation", borrowerName = "Steve", borrowDate = "2-11-2022" ), BorrowItem( id = 0, itemName = "XBox", borrowerName = "Steve", borrowDate = "2-11-2022" ) ) }
class BorrowItemsProvider : PreviewParameterProvider<BorrowItem> { override val values = sequenceOf(
BorrowItem( id = 0, itemName = "PlayStation", borrowerName = "Steve", borrowDate = "2-11-2022" ), BorrowItem( id = 0, itemName = "XBox", borrowerName = "Steve", borrowDate = "2-11-2022" ) ) }
@Preview @Composable fun BorrowedItemRowPreview( @PreviewParameter(BorrowItemsProvider::class) item: BorrowItem ) { BorrowedItemRow(
item ) }
@Preview @Composable fun BorrowedItemRowPreview( @PreviewParameter(BorrowItemsProvider::class) item: BorrowItem ) { BorrowedItemRow(
item ) }
Declutter using Groups
@MultiLocaleLightDarkPreview @Composable fun BorrowedItemRowDevicePreview() { BorrowTheme { BorrowedItemRow( item =
//.. ) } }
None
@Preview(locale = "en", group = "English") @Preview(locale = "fr-rCA", group
= "Canadian French") @Preview(locale = "es-rUS", group = "US Spanish") annotation class MultiLocalePreview
None
Local Inspection
None
@Composable fun BorrowedItemRow(item: BorrowItem) { var expanded by remember {
mutableStateOf(false) } // this will only affect previews if (LocalInspectionMode.current) { expanded = true } //.. }
@Composable fun BorrowedItemRow(item: BorrowItem) { var expanded by remember {
mutableStateOf(false) } // this will only affect previews if (LocalInspectionMode.current) { expanded = true } //.. }
Showkase
None
@ShowkaseComposable(group = "Individual rows") @Preview @Composable fun BorrowedItemRowExpandedPreview() { BorrowTheme
{ BorrowedItemRow( //.. ) } }
@ShowkaseComposable(group = "Individual rows") @Preview @Composable fun BorrowedItemRowExpandedPreview() { BorrowTheme
{ BorrowedItemRow( //.. ) } }
@ShowkaseComposable(group = "Individual rows") @Composable @Preview fun BorrowedItemRowCollapsedPreview() { CompositionLocalProvider(LocalInspectionMode
provides false) { BorrowTheme { BorrowedItemRow( //.. ) } } }
None
None
None
Animation Previews
None
None
updateTransition Supported Animations AnimatedVisibility animate*AsState rememberInfiniteTransition CrossFade AnimatedContent
Screenshot Testing
Available Options
Paparazzi Available Options
Paparazzi Roborazzi Available Options
Paparazzi Roborazzi Compose Preview Available Options
Paparazzi
Works on JVM Paparazzi
Works on JVM Based on Layoutlib Paparazzi
Works on JVM Based on Layoutlib Needs JUnit tests Paparazzi
Works on JVM Based on Layoutlib Needs JUnit tests Paparazzi
Supports Views
Works on JVM Based on Layoutlib Needs JUnit tests Paparazzi
Supports Views Emulates Production
class PaparazziTests { @get:Rule val paparazzi = Paparazzi( deviceConfig =
PIXEL_5.copy(nightMode = NightMode.NIGHT), renderingMode = RenderingMode.SHRINK ) }
class PaparazziTests { @get:Rule val paparazzi = Paparazzi( deviceConfig =
PIXEL_5.copy(nightMode = NightMode.NIGHT), renderingMode = RenderingMode.SHRINK ) }
class PaparazziTests { //.. @Test fun launchComposable() { paparazzi.snapshot {
BorrowTheme { BorrowedItemRow( item = //.. ) } } } }
class PaparazziTests { //.. @Test fun launchComposable() { paparazzi.snapshot {
CompositionLocalProvider(LocalInspectionMode provides true) { BorrowTheme { BorrowedItemRow( item = //.. ) } } } } }
class PaparazziTests { //.. @Test fun launchComposable() { paparazzi.snapshot {
CompositionLocalProvider(LocalInspectionMode provides true) { BorrowTheme { BorrowedItemRow( item = //.. ) } } } } }
Baseline
After changes
Failure Comparison
Compose Preview Screenshot
Works on JVM Compose Preview Screenshot
Works on JVM Based on Layoutlib Compose Preview Screenshot
Works on JVM Based on Layoutlib Fully Automated Compose Preview
Screenshot
Works on JVM Based on Layoutlib Fully Automated Compose Preview
Screenshot Needs a special directory
Works on JVM Based on Layoutlib Fully Automated Compose Preview
Screenshot Needs a special directory Emulates Debug
Compose Preview Screenshot - Source
Compose Preview Screenshot - Source @LightDarkThemePreview @Composable fun BorrowedItemRowPreview( @PreviewParameter(BorrowItemsProvider::class)
item: BorrowItem ) { BorrowedItemRow( item ) }
Compose Preview Screenshot - Destination
Screen Comparison
Screen Comparison
Can’t decide? sergio-sastre/ComposablePreviewScanner
Further Exploration https://github.com/takahirom/roborazzi Composable Preview Driven Development: TDD-fying your UI
with ease!
Questions?
Thank You! Chennai