Jetpack-Compose-Tutorials
Jetpack Compose Tutorials and Playground
🤓 Overview
Series of Tutorials to learn about Jetpack Compose, Material Widgets, State, Animation, and Navigation. Easy to search in code and in app. Each chapter module contains its own content in code. SearchBar can be used to search with a tag or description available for each tutorial.
Recommended section is under constructions for now, when finished it will get recommended tags using previous searches using a database, domain with ViewModel.

Tutorial | Preview |
---|---|
1-1 Column, Row, Box, ModifiersCreate Row that adds elements in horizontal order, and Column that adds elements in vertical order. • Column • Row • Box • Modifier |
![]() |
1-2 Surface, Shape, ClickableCreate and modify Surface to draw background for Composables, add click action to any composable. Set weight or offset modifiers. • Surface • Shape • Clickable |
![]() |
Material Widgets
Tutorial | Preview |
---|---|
2-1 TextCreate Text component with different properties such as color, background, font weight, family, style, spacing and others • Text • Row • FontStyle • Annotated String Hyperlink |
![]() |
2-2 Button, IconButton, FAB, ChipCreate button with text and/or with image, Floating Action Button or Chips. Modify properties of buttons including color, text, and click actions. • Button • IconButton • FloatingActionButton • Chip |
![]() |
2-3 TextFieldCreate TextField component with regular style or outlined. Set error, colors, state, icons, and IME actions. • TextField • OutlinedTextField • IME • Phone format VisualTransformation • Regex |
![]() |
2-4 ImageCreate Image with image, vector resource or with Painter, set image and Content scales to fit, expand or shrink image. Change shape of Image or apply ColorFilter and PorterDuff modes. • Image • Canvas • Drawable • Bitmap |
![]() |
2-5 LazyColumn/Row/VerticalGridVertical, horizontal grid lists with LazyColumn, LazyRow and LazyVerticalGrid. Use contentPadding set paddings for lists, verticalArrangement or horizontalArrangement for padding between items, rememberLazyListState to manually scroll. • LazyColumn(Vertical RecyclerView) • LazyRow(Horizontal RecyclerView • LazyVerticalGrid(GridLayout) • StickyHeaders |
![]() |
2-6 TopAppbar & TabTopAppbar with actions, overflow menus. Tabs with text only, image only and image+text with different background, divider, and indicators. • TopAppBar • Overflow menu • TabRow and Tab • Tab Indicator, Divider |
![]() |
2-7 BottomNavigationBottom navigation bars allow movement between primary destinations in an app. BottomNavigation should contain multiple BottomNavigationItems, each representing a singular destination. • BottomNavigation • BottomNavigationItem |
![]() |
2-8 BottomAppBarA bottom app bar displays navigation and key actions at the bottom of screens. • BottomAppBar • Scaffold |
![]() |
2-9-1 Side NavigationA backdrop appears behind all other surfaces in an app, displaying contextual and actionable content. • Scaffold • Side Navigation • DrawerState |
![]() |
2-9-2 ModalDrawerModal navigation drawers block interaction with the rest of an app’s content with a scrim. They are elevated above most of the app’s UI and don’t affect the screen’s layout grid. • ModalDrawer • DrawerState • Scaffold |
![]() |
2-10-1 BottomSheetCreate bottom sheet using BottomSheetScaffold and rememberBottomSheetScaffoldState, create modal bottom sheets. • BottomSheetScaffold • BottomSheetState • ModalBottomSheetLayout |
![]() |
2-10-4 BottomDrawerBottomDrawer with BottomAppBar. • BottomDrawer • BottomAppBar • Scaffold |
![]() |
2-10-5 BackdropScaffoldBackdropScaffold provides an API to put together several material components to construct your screen. |
![]() |
2-11 Snackbar, Progress, SelectionCreate Snackbars with various layouts and styling, Checkboxes with selectable text, tri state checkbox, grouped radio buttons and sliders. • SnackBar • ProgressIndicator • Checkbox • TriStateCheckbox • Switch • RadioButton • Slider • RangeSlider |
![]() |
2-12 Dialog, AlertDialogCreate Dialog, and AlertDialog with standard and custom layouts. Implement on dismiss logic and get result when dialog is closed. • AlertDialog • Dialog • DialogProperties |
![]() |
Layout
Tutorial | Preview | ||
---|---|---|---|
3-1-1 Custom ModifierCreate custom layout using using layout, Measurable, Constraint, Placeable. • Custom Modifier • Measurable • Constraint • Placeable |
![]() |
||
3-1-2 onGloballyPositionedUse Modifier.onGloballyPositioned to get position of a Composable in parent, root or window.br> • Modifier • onGloballyPositioned |
![]() |
||
3-1-3 graphicsLayerUse Modifier.offset{} and Modifier.graphicsLayer{} to scale, translate or change other properties of a Composable. • Modifier • graphicsLayer |
![]() |
||
3-1-4 BoxWithConstraintsBoxWithConstraints is a composable that defines its own content according to the available space, based on the incoming constraints or the current LayoutDirection. • BoxWithConstraints • Constraint |
![]() |
||
3-1-6 Chaining Size ModifiersObserve how chaining Modifier.size.size, Modifier.sizeIn.size or Modifier.size.requiredSize or other combination of size modifiers effect final Constraints. • Modifier • size/sizeIn • requiredWidth/requiredHeight/requiredSize |
![]() |
||
3-1-7 Modifier.wrapContentSizeUse Modifier.wrapContentSize/Width/Height to use content constraints instead of Constraints forced by parent. • Modifier • Custom Layout • Measurable |
![]() |
||
3-1-8 Modifier.layoutUse Modifier.layout to create LayoutModifier to measure with Constraints and place Placeables based on which order Modifier.layout is assigned. • Modifier • Custom Layout • Measurable • Constraints • Placeable |
![]() |
||
3-2-1 Custom LayoutCreate custom layout using using MeasurePolicy and use intrinsic dimensions. • Custom Layout • Measurable • Constraint • Placeable |
![]() |
||
3-2-10 Constraints & Modifier.layoutConstraints to measure measurables with Constraints.offset and Constraints.constrainWidth to limit maximum width or available space for Placeable. • Custom Layout • Measurable • Constraint • Placeable • Modifier.layout |
![]() |
||
3-3-1 Scope&ParentDataModifierAdd custom modifiers to Composable inside a custom layout using its scope like align modifier only available in specific Composable like a custom Column. • Custom Layout • Scope • ParentDataModifier • Measurable • Constraint • Placeable |
![]() |
||
3-5 SubcomposeLayoutSubcompose layout which allows to subcompose the actual content during the measuring stage for example to use the values calculated during the measurement as params for the composition of the children. • SubcomposeLayout • Constraint • Measurable • Constraint • Placeable |
![]() |
||
3-6-1 Custom Chat Layouts1Custom layout like whatsapp chat layout that moves time and message read status layout right or bottom based on message width. • Custom Layout • Measurable • Constraint • Placeable |
![]() |
||
3-6-2 Custom Chat SubcomposeLayoutCustom layout like whatsapp chat. Added quote and name tag resized to longest sibling using SubcomposeColumn from previous examples to have whole layout. • Custom Layout • SubcomposeLayout • Measurable • Constraint • Placeable |
![]() |
||
3-9 Visibility PercentageDetect percentage of visibility of a Composable using Modifier.onPlaced inside Column with vertical scroll or LazyColumn. • Modifier • LazyColumn • LazyListState • onPlaced |
![]() |
||
3-10 Center Item on ScrollDetect position in parent and center an item while its parent is scrolled. • Modifier • LazyColumn • onPlaced |
![]() |
||
State
Tutorial | Preview |
---|---|
4-1-1 Remember&MutableStateRemember and mutableState effect recomposition and states. • remember • State • Recomposition |
![]() |
4-2-3 Scoped RecompositionHow hierarchy of Composables effects Smart Composition. • remember • Recomposition • State |
![]() |
4-4 Custom RememberCreate a custom remember and custom component to have badge that changes its shape based on properties set by custom rememberable. • remember • State • Recomposition • Custom Layout |
![]() |
4-5-1 SideEffect1Use remember functions like rememberCoroutineScope, and rememberUpdatedState and side-effect functions such as LaunchedEffect and DisposableEffect. • remember • rememberCoroutineScope • rememberUpdatedState • LaunchedEffect • DisposableEffect |
![]() |
4-5-2 SideEffect2Use SideEffect, derivedStateOf, produceState and snapshotFlow. • remember • SideEffect • derivedStateOf • produceStateOf • snapshotFlow |
![]() |
4-7-3 Compose Phases3How deferring a state read changes which phases of frame(Composition, Layout, Draw) are called. • Modifier • Recomposition • Composition • Layout • Draw |
![]() |
4-12 LazyList Scroll DirectionDetect scroll direction of a LazyColumn using LazyListStated. • Modifier • LazyColumn • LazyListState • derivedStateOf • snapshotFlow |
![]() |
Gesture
Tutorial | Preview |
---|---|
5-1-1 ClickableUse clickable modifier, Indication. Indication to clip ripples, or create custom ripple effects. • clickable • Indication • rememberRipple • pointerInput • pointerInteropFilter |
![]() |
5-1-2 InteractionSource1Use Interaction source to collect interactions or change scale of Composables based on interaction state. • clickable • InteractionSource |
![]() |
5-1-3 InteractionSource2Use InteractionSource to update touch state of multiple Composable or another Composable based on current interaction. • clickable • InteractionSource |
![]() |
5-2 Tap&Drag GestureUse PointerInput to listen press, tap, long press, drag gestures. detectTapGestures is used for listening for tap, longPress, doubleTap, and press gestures. • pointerInput • pointerInteropFilter • detectTapGestures • detectDragGestures • onPress • onDoubleTap |
![]() |
5-3 Transform GesturesUse PointerInput to listen for detectTransformGesture to get centroid, pan, zoom and rotate params. • pointerInput • detectTransformGestures • centroid • pan • zoom |
![]() |
5-4-1 AwaitPointerEventScope1Use AwaitPointerEventScope to get awaitFirstDown for down events, waitForUpOrCancellation for up events, and awaitPointerEvent for move events with pointers. • AwaitPointerEventScope • PointerInputChange • awaitFirstDown • waitForUpOrCancellation • awaitPointerEvent • awaitTouchSlopOrCancellation • awaitDragOrCancellation |
![]() |
5-4-3 Centroid, Zoom, Pan, RotationUse AwaitPointerEventScope to calculate centroid position and size, zoom, pan, and rotation. • AwaitPointerEventScope • centroid • pan • zoom |
![]() |
5-6-2 Gesture Propagation1Consume different type of touch events in Composable in an hierarchy to display gesture propagation between parent and children with MOVE gestures. • AwaitPointerEventScope • pointerInput • consume • consumePositionChange • anyChangeConsumed |
![]() |
5-6-4 Transform PropagationConsume events to rotate, zoom, move or apply drag or move events on Composables. • AwaitPointerEventScope • detectTransformGestures • consume • consumePositionChange • anyChangeConsumed • pan • zoom |
![]() |
5-9-6 Collapsing TopAppBarCreate a collapsing TopAppBar using Modifier.nestedScroll and NestedScrollConnection. • nestedScroll • NestedScrollConnection |
![]() |
5-9-7 Collapsing TopAppBar2Create a collapsing TopAppBar using Modifier.nestedScroll and NestedScrollConnection. • nestedScroll • NestedScrollConnection |
![]() |
5-10-1 Image Touch DetectionDetect touch position on image and get color at touch position. • Image • AwaitPointerEventScope |
![]() |
5-11 Zoomable LazyColumnZoom images inside a LazyColum. • Image • Zoom • AwaitPointerEventScope |
![]() |
Graphics
Tutorial | Preview |
---|---|
6-1-1 Canvas Basics 1Use canvas draw basic shapes like line, circle, rectangle, and points with different attributes such as style, stroke cap, brush. • Canvas • DrawScope • Path • Path Effect |
![]() |
6-1-2 Canvas Basics 2Use canvas to draw arc, with path effect, stroke cap, stroke join, miter and other attributes and draw images with src, dst attributes. • Canvas • DrawScope • Path • Path Effect |
![]() |
6-1-3 Canvas PathsUse canvas to draw path using absolute and relative positions, adding arc to path, drawing custom paths, progress, polygons, quads, and cubic. • Canvas • DrawScope • Path • Path Effect |
![]() |
6-1-4 Canvas Path OpsUse canvas to clip paths, or canvas using path, or rectangle with operations such as Difference, Intersect, Union, Xor, or ReverseDifference.. • Canvas • DrawScope • Path • PathOperation • ClipOperation |
![]() |
6-1-5 Canvas Path SegmentsUse canvas to flatten Android Path to path segments and display PathSegment start and/or end points. • Canvas • DrawScope • Path • PathSegment |
![]() |
6-1-6 Canvas PathEffectUse PathEffect such as dashedPathEffect, cornerPathEffect, chainPathEffect and stompedPathEffect to draw shapes add path effects around Composables • Canvas • DrawScope • Path • Path Effect |
![]() |
6-2-1 Blend(Porter-Duff) ModesUse blend(Porter-Duff) modes to change drawing source/destination or clip based on blend mode ,and manipulate pixels. • Canvas • DrawScope • Path • Path Effect • BlendMode |
![]() |
6-2-3 Multi-Color VectorDrawableUse blend(Porter-Duff) to create multi colored VectorDrawables or VectorDrawables with fill/empty animations • Canvas • DrawScope • VectorDrawable • BlendMode |
![]() |
6-4-2 Drawing AppDraw to canvas using touch down, move and up events using array of paths to have erase, undo, redo actions and set properties for each path separately. • Canvas • DrawScope • Path • AwaitPointerEventScope • PointerInputChange • BlendMode |
![]() |
6-5 Color PickerColor Picker that calculates angle from center and gets a color using hue and returns a color as in HSL or RGB color model. • Canvas • DrawScope • Path • AwaitPointerEventScope • PointerInputChange • BlendMode |
![]() |
6-6 Scale/Translation EditEditable Composable that changes position and scale when touched and dragged from handles or changes position when touched inside. • Canvas • DrawScope • Scale • Translate • AwaitPointerEventScope • PointerInputChange |
![]() |
6-7 Gooey EffectCreate basic Gooey Effect with static circles and one with moves with touch. • Canvas • DrawScope • Gooey • Translate • AwaitPointerEventScope • PointerInputChange |
![]() |
6-8-1 Cutout Arc ShapeUse Path.cubicTo, Path.arcTo to draw cutout shape. • Canvas • Path • Scale |
![]() |
6-9-1 Neon Glow EffectUse paint.asFrameworkPaint() to create blur effect to mimic neon glow and infinite animation to dim and glow infinitely. • Canvas • Path • Neon • AwaitPointerEventScope • PointerInputChange |
![]() |
6-11 Canvas Erase PercentageUse blend(Porter-Duff) modes with androidx.compose.ui.graphics.Canvas to erase and compare pixels with erased Bitmap to find ou percentage of erased area. • ActualCanvas • Path • AwaitPointerEventScope • PointerInputChange |
![]() |
6-12 Diagonal Price TagUse Modifier.drawBehind and Modifier.composed to draw diagonal price tag with shimmer effect • TextMeasurer • Canvas • Composed • Brush • Image |
![]() |
6-13 Border ProgressUse Path segments to create path with progress to display remaining time • Canvas • Path • PathSegment |
![]() |
6-14 Pie ChartDraw pie chart with dividers, and text between angles. • Canvas • Path • Animatable • TextMeasurer |
![]() |
6-15 Pie Chart with Touch AnimationAnimate Pie Chart on touch and get data of touched section. • Canvas • Path • Animatable • TextMeasurer • detectTapGestures |
![]() |
6-17 Animated Rainbow BorderDraw animated rainbow color border using BlendMode.SrcIn and Modifier.drawWithCache • Canvas • Shape • BlendMode • Brush |
![]() |
6-20 PathParser and PathMeasureCreate Path from string and animate segments via PathMeasure. • Canvas • Path • PathParser • PathMeasure • PathSegment • animateFloatAsState |
![]() |
6-21 Constant Velocity AnimationCreate constant time animation. • Canvas • animateOffsetAsState • animateValueAsState |
![]() |
6-23 Tab/Switch AnimationCreate a Tab/Switch with fluent blending text and shadow. • Canvas • BlendMode • animateDpAsState |
![]() |
6-24 Projection change with LerpAnimate projection of rotating circle between inner and outer projection with lerp function. • Canvas • rememberInfiniteTransition • animateFloatAsState |
![]() |
6-25 BeforeAfter LayoutCreate animatable BeforeAfter layout with Generic or BlendMode. • Generic Shape • BlendMode • rememberInfiniteTransition • animateFloatAsState |
![]() |
Stability, Skippable, Restartable
Add snippet below to app's gradle module
subprojects {
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
if (project.findProperty("composeCompilerReports") == "true") {
freeCompilerArgs += [
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" +
project.buildDir.absolutePath + "/compose_compiler"
]
}
if (project.findProperty("composeCompilerMetrics") == "true") {
freeCompilerArgs += [
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" +
project.buildDir.absolutePath + "/compose_compiler"
]
}
}
}
}
And run task to check for compiler reports for stability inside build/compiler_reports
./gradlew assembleRelease -PcomposeCompilerReports=true
Some of the answers i posted on Stackoverflow
Composable Functions, Recomposition
Difference Between Composable and Normal Functions
What does Jetpack Compose remember actually do, how does it work under the hood?
Scoped/Smart Recomposition
Why does mutableStateOf without remember work sometimes?
Lambdas, Scopes, and Recomposition
MutableState vs MutableStateFlow
Destructuring MutableState
Does a 0dp sized composable even get composed
** Jetpack Compose - Recomposition ignoring function parameter
Unable to call @Composable function from remember block
Composable doesn't re-compose on button click
Jetpack Compose - avoid unnecessary recomposition
In compose, why modify the properties of the List element, LazyColumn does not refresh
Composables
How to get exact size without recomposition?
When should I use Android Jetpack Compose Surface composable?
How can I select only 3 element in a grid/list (jetpack compose)?
Android Compose: Difference between LazyColumn and Column with verticalScroll
Remove default padding from CheckBox
How to give different color to textDecoration?
Jetpack compose custom snackbar material 3
How to place hanging icon in upper right corner of Card composable
Icon drawable inside IconButton is black despite it being white
What is clickable indication in jetpack compose?
LaunchedEffect, SideEffect, DerivedStateOf, snapshotFlow
Using SnapshotFlow to observe MutableState changes
Callback function can be changed in Compose? rememberUpdatedState
How can I launch a function only onetime when I use Jetpack Compose?
Does lazyColumn listen for events when items enter or leave the screen
Why do I need use derivedStateOf in Compose?
Click a close button on a bottomsheet to hide it in compose
How to show a composable just for e few seconds?
What would be the most 'lightweight' way to observe current time for a an android composable?
Difference between remember and rememberUpdatedState in Jetpack Compose?
Use of LaunchedEffect vs SideEffect in jetpack compose
Jetpack Compose recomposition race condition
how can I do resend email timer LaunchedEffect
LaunchedEffect vs rememberCoroutineScope. This explanation makes me confused. Please make it clear to me
MutableState callback in non-Composable
Modifiers
Jetpack Compose - Order of Modifiers
Create Custom Modifier
Composed Modifier
Why are the modifier sizes not overwritten?
How to achieve layout with where icon is position absolute on column layout Modifier.offset
Define Custom Boundaries for a Composable GraphicsLayer
Modifier- Is there a way to create and apply a style to multiple elements in Compose like we do with CSS
JetPack Compose - weight() in Row in Card doesn't work
How to calculate empty space in lazy column after last visible item
How To Get The Absolute Position Of My Composable Function/Children?
Use of LaunchedEffect vs SideEffect in jetpack compose
Layout, Constraints
Creating a SearchView
Create custom badges with size and colorful shadows
How to align one item to bottom using weight or Layout
How to create chat bubbles
Custom Tabs
Take screenshot of a Composable
Make last Item of the Compose LazyColumn fill rest of the screen
Row IntrinsicSize.Min not working when the children are async loading images SubcomposeLayout
Observing position of item in Lazy Column in Jetpack Compose
Jetpack Compose width / height / size modifier vs requiredWidth / requiredHeight / requiredSize
Jetpack Compose - layouting reusable components
Can't represent a size of 357913941 in Constraints in Jetpack Compose
Android compose, Indicator size problem with coil
SubcomposeLayout
How does SubcomposeLayout work?
How to create a Slider with SubcomposeLayout
Setting width of 2 buttons with SubcomposeLayout
How to adjust size of component to it's child and remain unchanged when it's child size will change?
Get information about size before is drawn in Compose
Animation
Animating with single recomposition with Canvas
Android Compose create shake animation
Issue with jetpack compose animation performance
animation o a lazycolumn android
Rotate Animation Compose
How to animate Rect position with Animatable?
Gestures
How gestures work in Jetpack Compose and onTouchEvent
Detect which section of image is touched
Detect when the user lifts their finger (off the screen)
How to detect the end of transform gesture in Jetpack Compose?
Combine detectTapGestures and detectDragGesturesAfterLongPress?
What is clickable indication in jetpack compose?
Prevent dragging box out of the screen with Jetpack Compose
JetPack Compose: Adding click duration
compose gestures, zoom in zoom out move and rotation
How to set Double back press Exit in Jetpack Compose?
Jetpack Compose detect drag gesture and detect Interaction source
How can one composible's clicks pass through to a composible underneath?
Canvas, DrawScope
How to apply Porter-Duff mode to image?
How to create drawing app with Jetpack Compose?
How to create HSL saturation and lightness change gradient or brush editor with Jetpack Compose?
How to create Angular gradient in Jetpack compose?
Angled gradient background in Jetpack Compose
how to draw a square with stroke and neon glow with Jetpack Compose Canvas?
Jetpack compose Drawing over shapes in a path
Cubic with Canvas
What is the unit of Canvas's size when I use Compose?
How to draw a multicolored bar with Canvas in Jetpack Compose?
How to clip or cut a Composable with BlendModes?
How to center Text in Canvas in Jetpack compose?
How to divide the stroke of a circle at equal intervals in Jetpack compose canvas?
Jetpack compose custom shape with pie effect
How to apply PathEffect without using Stroke with Jetpack Compose?
Jetpack Compose - CardView with Arc Shape on border
Jetpack Compose: how to cut out card shape?
Jetpack Compose: How to create a rating bar?
Watermark or write on Bitmap with androidx.compose.ui.graphics.Canvas?
Image Cropper
Vertical scroll on Canvas (Jetpack Compose)
Why can I draw a line out of the canvas when I use Jetpack Compose?
implement a spinning activity indicator with Jetpack Compose
Resources and References
Codelab Jetpack Compose Basics
Codelab Jetpack Compose Layouts
Codelab Jetpack Compose States
Codelab Jetpack Compose Advanced State
Developer Android
Developer Android Material
Jetpack Compose Samples
Under the hood of Jetpack Compose — part 2 of 2- Leland Richardson
What is “donut-hole skipping” in Jetpack Compose?-Vinay Gaba
Android Graphics
Playing with Paths-Nick Butcher
Custom Shape with Jetpack Compose-Julien Salvi
Porter Duff Mode
Porter/Duff Compositing and Blend Modes
Practical Image PorterDuff Mode Usage in Android-Elye
Android Image Lighting Control and Color Filtering-Elye
Android Image Color Change With ColorMatrix-Elye
Manipulating images and Drawables with Android’s ColorFilter-Nick Rout
Curved (Cut out) Bottom Navigation With Animation in Android
Gooey Effect Using Canvas API In Android
movableContentOf and movableContentWithReceiverOf-Jorge Castillo
Jetpack Compose Stability Explained-Ben Trengrove
Composable metrics-Chris Banes
Creating a particle explosion animation in Jetpack Compose-Omkar Tenkale