Diving into advanced Compose Multiplatform
Modifiers and their impact on Multiplatform
development
Meike Felicia Hammer @feliciaf_aye
Slide 2
Slide 2 text
Skin Color
chromatophores
skin cells
Skin Texture
Body Shape
in-/de
fl
ate internal
chambers
Behaviour
Pattern
imitating
crabs
papillae
muscles
Slide 3
Slide 3 text
size, layout, behaviour, appearance
additional information
user input
clickable, scrollable, draggable, zoomable, focusable
Decorate and
augment
Composables.
Modi
f
iers
Slide 4
Slide 4 text
Modi
f
iers
Usually read top to bottom
Unintuitive in some cases 👀
Slide 5
Slide 5 text
Text
Padding
-
Background
-
Border
ORDER MATTERS
Text Text
Slide 6
Slide 6 text
ORDER MATTERS
Border
-
Size
-
Padding
-
Border
Slide 7
Slide 7 text
ORDER MATTERS
Scale
-
Offset
Slide 8
Slide 8 text
Combination fun
Size Modifiers
Layout
size
requiredSize
padding
f
illMaxSize
sizeIn
wrapContentSize
Slide 9
Slide 9 text
What happens when we
chain fillMaxSize and
requiredSize?
Force it
requiredSize()
Slide 10
Slide 10 text
Chaining multiple size modifiers
does not work.
Size Modifier
A node has to adhere to its
bounds set by the first size
modifier.
Slide 11
Slide 11 text
Data Composition Layout Drawing UI
size clip
padding rotate
Modifiers in different phases
Slide 12
Slide 12 text
Layout phase
-
Constraints
From parent to
child in
the UI Tree
during the layout
phase.
When node has
measured its own
size, it
communicates size
back up to the tree.
Parent measures
its children.
Slide 13
Slide 13 text
Multiplatform
Modifiers
Slide 14
Slide 14 text
Compose Multiplatform independently
renders components from scratch
on each platform using Skia.
No platform-native widgets.
Material and Material 3 widgets out of the box.
Behind Modifiers
Slide 15
Slide 15 text
Rendering
Compose
Skia
iOS
Desktop
Canvas API
Web Android
Skiko
Skia for rendering on
Android
Skiko for other
platforms
(
Skia for
Kotlin)
Slide 16
Slide 16 text
Modify platform UIs
all at once?
Everything as
expected?
Slide 17
Slide 17 text
Differences?
Slide 18
Slide 18 text
Discard and Save
Shortcuts
Discard Ctrl =
Save Ctrl -
Slide 19
Slide 19 text
Advanced
Modi
f
iers
Slide 20
Slide 20 text
Drawing Modifiers
drawWithContent
Base drawing modifier, controls drawing order and commands.
drawBehind
Wrapper for drawWithContent, draws behind content.
drawWithCache
Uses onDrawBehind/onDrawWithContent.
Objects used during drawing are cached,
until size changes or state variables change.
Graphics Modifiers
Additionally to the Canvas
Composable
Slide 21
Slide 21 text
No need to
maintain your
own state
DrawScope
Declarative,
stateless
drawing API
Draw
Shapes,
Paths,
…
Access to size and center of the drawing area.
Slide 22
Slide 22 text
Canvas Composable
For simple drawings.
Convenience Wrapper (drawBehind).
Under the hood.
Use .dp and
convert it to
pixels before
drawing.
Pixels.
Cuttlefish Camouflage
Fish - First Photo by David Clode on Unsplash
Bee - Second Photo by Boris Smokrovic on Unsplash
Frog - Third Photo by Ray Hennessy on Unsplash
Slide 31
Slide 31 text
Cuttlefish
Camouflage
Slide 32
Slide 32 text
Size and Placement
Only affects
the draw
phase.
Can become
invisible, when
drawing
outside of
bounds.
Graphics Layer Modifiers
Does not change
measured size +
placement of a
Composable.
Slide 33
Slide 33 text
Size and Placement
Graphics Layer Modifiers
Slide 34
Slide 34 text
DEMO
Layout Modifier
Growing Box
Slide 35
Slide 35 text
Growing Box
Slide 36
Slide 36 text
Growing Box
Slide 37
Slide 37 text
Size and Placement
Growing Box
200 300
Slide 38
Slide 38 text
Make it reusable and
environment-friendly.
Custom Compose Modifiers
Slide 39
Slide 39 text
Theory
Chain existing
modifiers
together if you
can.
Composable
function
modifiers are
never skipped
(performance).
Composable
function
modifiers must
be called within
a composable
function.
Slide 40
Slide 40 text
Chained Modifiers
Slide 41
Slide 41 text
UpsideDown
Simple Draw
Modifier
Slide 42
Slide 42 text
Continue the modifier chain.
Reference this or previously added modifiers are dropped.
Use this then Modifier or implicitly return graphicsLayer …
Modifier Factory
Slide 43
Slide 43 text
Composition Local
Slide 44
Slide 44 text
Composition Local
Node API
Slide 45
Slide 45 text
Composition Local
Node API
Slide 46
Slide 46 text
Composition Local
-
Node API
Slide 47
Slide 47 text
Modifier Node Element
Implement equals and hashCode
If not unnecessarily updated
(poor performance)
Use data class
Node API
80 % faster
Super secret text
Lorem ipsum dolor.
Slide 48
Slide 48 text
Composable Modifier vs composed Factory vs Node API
Simple behaviour/decoration?
Custom modifier with state/effects/multipleSteps?
Fine grained control while performance is critical?
Node API
(
Best practice)
composed Factory
Composable Modifier
Yes
No
No
No
Composable Modifier
Yes
Yes
Node API
Slide 49
Slide 49 text
Modi
f
ier
Madness
Slide 50
Slide 50 text
Visual differences
MADNESS 1/3
Same Modifiers
Different
appearance/
behaviour
Example
Focus
animation
behaviour
Write custom Modifier, but then ..
MADNESS 2/3
Features
GraphicsLayer#toImageBi
tmap
(
Compose 1.7.+)
ByteReadChannel
.toBitmap()
Import exists,
but not at runtime.
androidx.compose.ui.
graphics.asImageBit
map
.lazyBackgroundImage
.removeBackground
Slide 56
Slide 56 text
DEMO
ImageDownload
Platform specific stuff needed 🫣
Slide 57
Slide 57 text
Image Download
Slide 58
Slide 58 text
Image Download
.lazyBackgroundImage
Slide 59
Slide 59 text
Image Download
Android
Desktop + iOS
Slide 60
Slide 60 text
Performance
Skiko and Skia
ensure consistent performance on all platforms.
Composable function modifiers
are never skipped.
ModifierNodeElement
must implement equals and hashCode.
MADNESS 3/3
Slide 61
Slide 61 text
Embrace
different input
options.
Impact on Multiplatform development
Most enjoyable
with less
platform specific
code.
Smooth
transition from
Android Jetpack
Compose.
Modify all of them at once.
UI behaviour
can be slightly
different then
expected.
Slide 62
Slide 62 text
@feliciaf_aye
Thank you,
and don’t forget
to vote