components are not bound to specific activity or fragment
state is explicit and passed to composable as parameter(?)
accelerate development
compose is compatible with all your existing code
most common libs are working with compose
e.g. Navigation, ViewModel, Kotlin coroutines
Android Studio support
Previews
also multiple(!)
Powerful
accessibility
animations
using MaterialDesign possible
Quick start
build features
compose true
composeOptions
KotlinCompilerExtensionVersion
→ get from “Compatibility Map”
Try Jetpack Compose sample apps
Thinking in Compose
declarative (instead of imperatively mutating frontend views)
The declarative programming paradigm
regenerating the entire screen from scratch, then applying only necessary changes
regenerating is expensive but:
Compose intelligently chooses which part of the UI should be redrawn
A simple composable function
@Composable annotation
the function takes in data
the function is idempotent
if it is called multiple times it behaves in the same way
The declarative paradigm shift
imperative way:
instantiate the tree of widgets (usually from XML file)
declarative approach
widgets are (relatively) stateless and do not expose getter/setter methods
update UI ⇒ calling the same composable function with the different arguments
when the user interacts with the UI, the UI raises events (e.g. onClick). Those events should notify the app logic, which changes the app state. When the app state changes, the composable functions are called again with the new data. The UI elements will be redrawn. This process is called recomposition.
Dynamic content
because it is Kotlin, the composable functions are dynamic (e.g. we can use if/else/loops etc)
Recomposition
in imperative way → call setter
in declarative way → call the same composable function again with the new data
⇒ widgets will be recomposed
Recomposition can be expensive
⇒ intelligent recomposition
if you need to do expensive work (w.g. reading from shared preferences), do it in the background coroutine and pass the result to composable function as parameter
This document discusses a number of things to be aware of when use Compose:
Composable functions can execute in any order
example:
StartScreen()
MiddleScreen()
EndScreen()
each function can be called in any order
Composable functions can run in parallel
making use of multiple cores
composable can run within a pool of background threads
⇒ composable functions should have no side-effects. Instead, trigger side-effects from callbacks (e.g. onClick) that always execute on UI thread.
Recomposition skips as much as possible
Recomposition is optimistic
Composable functions can run quite frequently
for expensive work use:
mutableStateOf
LiveData
Using the Bill of Material
Compose BOM lets you manage all of your Compose library versions by specifying only BOM's version.
see “BOM to library version mapping”
Compose Compiler library not included to BOM
this makes sure that you are using the version of compiler compatible to your Kotlin version
see “Compose to Kotlin compatibility map”
To use different from BOM library version simply declare it explicitly
No version declared ⇒ use the version from “BOM map”
Using BOM assures that versions of Compose libraries are compatible, but BOM doesn't add those libraries.