Androidv14 - Level34
- Foundation
- Development environment
- Design
- Adopting Compose
- Additional resources
- Less code
- Intuitive
- Accelerate development
- Powerful
- Create a new app with support for Compose
- Set up Compose for an existing app
- Try Jetpack Compose sample apps
- The declarative programming paradigm
- A simple composable function
- The declarative programming paradigm
- Dynamic content
- Recomposition
- Composable functions can execute in any order
- Composable functions can run in parallel
- Recomposition skips as much as possible
- Recomposition is optimistic
- Composable functions might run quite frequently
- Why isn't the Compose Compiler library included in the BOM?
- How do I use a different library version than what's designated in the BOM?
- Does the BOM automatically add all the Compose libraries to my app?
- Why is the BOM the recommended way to manage Compose library versions?
- Am I forced to use the BOM?
- Does the BOM work with version catalogs?
- Lifecycle overview
- Anatomy of a composable in Composition
- Add extra information to help smart recompositions
- Skipping if the inputs haven't changed
- State and effect use cases
LaunchedEffect
: run suspend functions in the scope of a composablerememberCoroutineScope
: obtain a composition-aware scope to launch a coroutine outside a composablerememberUpdatedState
: reference a value in an effect that shouldn't restart if the value changesDisposableEffect
: effects that require cleanupSideEffect
: publish Compose state to non-Compose codeproduceState
: convert non-Compose state into Compose statederivedStateOf
: convert one or multiple state objects into another statesnapshotFlow
: convert Compose's State into Flows
- Restarting effects
- Constants as keys
- The three phases of a frame
- Understand the phases
- State reads
- Phased state reads
- Phase 1: Composition
- Phase 2: Layout
- Phase 3: Drawing
- Optimizing state reads
- Recomposition loop (cyclic phase dependency)
- State and composition
- State in composables
- Other supported types of state
- Stateful versus stateless
- State hoisting
- Restoring state in Compose
- Ways to store state
- State holders in Compose
- Retrigger remember calculations when keys change
- Store state with keys beyond recomposition
- Best practice
- Types of UI state and UI logic
- UI state
- Logic
- UI logic
- Composables as state owner
- No state hoisting needed
- Hoisting within composables
- Plain state holder class as state owner
- Business logic
- ViewModels as state owner
- Screen UI state
- UI element state
- UI logic
- Best practice
- Verify state restoration
- Business logic
- Best practice
SavedStateHandle
APIs- Summary
- Unidirectional data flow
- Unidirectional data flow in Jetpack Compose
- Define composable parameters
- Events in Compose
- ViewModels, states, and events: an example
- Layers
- Design principles
- Control
- Customization
- Picking the right abstraction
- Introducing
CompositionLocal
**** - Creating your own
CompositionLocal
****- Deciding whether to use
CompositionLocal
**** - Creating a
CompositionLocal
**** - Providing values to a
CompositionLocal
**** - Consuming the
CompositionLocal
****
- Deciding whether to use
- Alternatives to consider
- Pass explicit parameters
- Inversion of control
- Setup
- Get started
- Create a NavController
- Create a NavHost
- Navigate to a composable
- Navigate with arguments
- Retrieve complex data when navigating
- Add optional arguments
- Deep links
- Nested Navigation
- Integration with the bottom nav bar
- Type safety in Navigation Compose
- Interoperability
- Navigate from Compose with Navigation for fragments
- Testing
- Testing the
NavHost
**** - Testing navigation actions
- Testing the
- Goals of layouts in Compose
- Basics of composable functions
- Standard layout components
- The layout model
- Performance
- Using modifiers in your layouts
- Scrollable layouts
- Responsive layouts
- Constraints
- Slot-based layouts
- Order of modifiers matters
- Built-in modifiers
padding
andsize
****- Offset
- Scope safety in Compose
matchParentSize
inBox
****weight
inRow
andColumn
****
- Extracting and reusing modifiers
- Best practices for reusing modifiers
- Modifiers in the UI tree
- Constraints in the layout phase
- Types of constraints
- How constraints are passed from parent to child
- Modifiers that affect constraints
size
modifierrequiredSize
modifierwidth
andheight
modifierssizeIn
modifier
- Examples
- Chain existing modifiers together
- Create a custom modifier using a composable modifier factory
- Implement custom modifier behavior using
Modifier.Node
****- Implement a custom modifier using
Modifier.Node
****
- Implement a custom modifier using
- Common situations using
Modifier.Node
****- Zero parameters
- Referencing composition locals
- Animating modifier
- Sharing state between modifiers using delegation
- Opting out of node auto-invalidation
- Actions, Alignment, Animation, Border, Drawing, Focus, Graphics, Keyboard, Layout, Padding, Pointer, Position, Semantics, Scroll, Size, Testing, Transformations, Other
HorizontalPager
****VerticalPager
****- Lazy creation
- Load more pages offscreen
- Scroll to an item in the pager
- Get notified about page state changes
- Add a page indicator
- Apply item scroll effects to content
- Custom page sizes
- Content padding
- Customize scroll behavior
- Snap distance
- Basic usage
- Features of flow layout
- Main axis arrangement: horizontal or vertical arrangement
- Cross axis arrangement
- Individual item alignment
- Max items in row or column
- Item weights
- Fractional sizing
- Use the layout modifier
- Create custom layouts
- Layout direction
- Custom layouts in action
- Make large layout changes for screen-level composables explicit
- Flexible nested composables are reusable
- Ensure all data is available for different sizes
- Implement UI pattern with
ListDetailPaneScaffold
****- Declare dependencies
- Basic usage
- Create custom alignment lines
- Intrinsics in action
- Intrinsics in your custom layouts
- Get started with
ConstraintLayout
**** - Decoupled API
ConstraintLayout
concepts- Guidelines
- Barriers
- Chains
- Material components in Compose
- Example
- Top app bars
- API surface
- Scroll behavior
- Examples
- Small
- Center aligned
- Medium
- Large
- Bottom app bar
- API surface
- Filled button
- Filled tonal button
- Outlined button
- Elevated button
- Text button
- API surface
- Floating action button
- Small button
- Large button
- Extended button
- Basic implementation
- Advanced implementations
- Filled card
- Elevated Card
- Outlined Card
- Limitations
- API surface
- Assist chip
- Filter chip
- Input chip
- Suggestion chip
- Elevated chip
- Alert dialog
- Dialog composable
- Basic example
- Advanced example
- API Surface
- Determinate indicators
- Indeterminate indicators
- Basic implementation
- Advanced implementation
- Range slider
- Basic implementation
- Advanced implementation
- Custom thumb
- Custom colors
- Example
- Basic example
- Snackbar with action
- Lazy lists
LazyListScope
DSL- Lazy grids
- Lazy staggered grid
- Content padding
- Content spacing
- Item keys
- Item animations
- Sticky headers (experimental)
- Reacting to scroll position
- Controlling the scroll position
- Large data-sets (paging)
- Tips on using Lazy layouts
- Avoid using 0-pixel sized items
- Avoid nesting components scrollable in the same direction
- Beware of putting multiple elements in one item
- Consider using custom arrangements
- Consider adding
contentType
**** - Measuring performance
- Strings
- String plurals (experimental)
- Dimensions
- Colors
- Vector assets and image resources
- Animated Vector Drawables
- Icons
- Fonts
- Dependency
- Experimental APIs
- Material theming
- Color scheme
- Typography
- Shapes
- Emphasis
- Elevation
- Material components
- Navigation components
- Customize a component's theming
- System UI
- Ripple
- Overscroll
- Accessibility
- Color accessibility
- Typography accessibility
- Large screens
- Approaches
- When to migrate
- Phased approach
- Dependencies
- Experimental APIs
- Theming
- Color
- Typography
- Shape
- Components and layouts
- Scaffold, snackbars and navigation drawer
- Top app bar
- Bottom navigation / Navigation bar
- Buttons, icon buttons and FABs
- Switch
- Surfaces and elevation
- Emphasis and content alpha
- Backgrounds and containers
- Views interoperability
- Color
- Using theme colors
- Surface and content color
- Content alpha
- Dark theme
- Typography
- Using text styles
- Shape
- Using shapes
- Default styles
- Theme overlays
- Component states
- Ripples
- Extending Material Theming
- Using Material components
- Replacing Material systems
- Using Material components
- Implementing a fully-custom design system
- Using Material components
- Theme system classes
- Theme system composition locals
- Theme function
- Theme object
- Display text from resource
- Common text stylings
- Change text color
- Change text size
- Make text italic
- Make text bold
- Add shadow
- Add multiple styles in text
- Enable advanced styling with
Brush
****- Use a brush for text styling
- Integrations
- Set text alignment
- Add multiple styles in a paragraph
- Adjust line height and padding
- Limit visible lines
- Indicate text overflow
- Choose
TextField
implementation - Style
TextField
**** - Style input with Brush API
- Implement colored gradients using
TextStyle
****
- Implement colored gradients using
- Set keyboard options
- Format input
- Clean input
- Best practices with state
- Select text
- Get position of a click on text
- Click with annotation
- Set font
- Downloadable fonts
- Use downloadable fonts programmatically
- Add fallback fonts
- Debug your implementation
- Caveats
- Use variable fonts
- Load a variable font
- Use custom axes
- Interoperatibility
- Extending from
ComponentActivity
**** - Extending from
AppCompatActivity
****
- Extending from
- Troubleshooting
- Load an image from the disk
- Drawable support
- Load an image from the internet
Coil
Glide
ImageBitmap
ImageVector
- Content scale
- Clip an
Image
composable to a shape - Add a border to an
Image
composable - Set a custom aspect ratio
- Color filter - Transform pixel colors of image
- Tinting an image
- Applying an
Image
filter with color matrix
- Blur an
Image
composable
- Only load the size of the bitmap you need
- Don’t store a bitmap in memory longer than you need it
- Don’t package large images with your AAB/APK file
- Basic drawing with modifiers and
DrawScope
- Coordinate system
- Basic transformations
- Scale
- Translate
- Rotate
- Inset
- Multiple transformations
- Common drawing operations
- Draw text
- Draw image
- Draw basic shapes
- Draw path
- Accessing
Canvas
object
- Drawing modifiers
Modifier.drawWithContent
: Choose drawing orderModifier.drawBehind
: Drawing behind a composableModifier.drawWithCache
: Drawing and caching draw objects
- Graphics modifiers
Modifier.graphicsLayer
: Apply transformations to composables
- Write contents of a composable to a bitmap
- Custom drawing modifier
- Gradient brushes
- Change distribution of colors with
colorStops
**** - Repeat a pattern with
TileMode
**** - Change brush Size
- Change distribution of colors with
- Use an image as a brush
- Advanced example: Custom brush
- AGSL
RuntimeShader
brush
- AGSL
- Animate common composable properties
- Animate appearing / disappearing
- Animate background color
- Animate the size of a composable
- Animate position of composable
- Animate padding of a composable
- Animate elevation of a composable
- Animate text scale, translation or rotation
- Animate text color
- Switch between different types of content
- Animate whilst navigating to different destinations
- Repeat an animation
- Start an animation on launch of a composable
- Create sequential animations
- Create concurrent animations
- Optimize animation performance
- Change animation timing
- Built-in animated composables
- Animate appearance and disappearance with
AnimatedVisibility
**** - Animate based on target state with
AnimatedContent
**** - Animate between two layouts with
Crossfade
****
- Animate appearance and disappearance with
- Built-in animation modifiers
- Animate composable size changes with
animateContentSize
****
- Animate composable size changes with
- List item animations
- Animate a single value with
animate*AsState
**** - Animate multiple properties simultaneously with a transition
- Use transition with
AnimatedVisibility
andAnimatedContent
**** - Encapsulate a transition and make it reusable
- Use transition with
- Create an infinitely repeating animation with
rememberInfiniteTransition
- Low-level animation APIs
Animatable
: Coroutine-based single value animationAnimation
: Manually controlled animation
- Animated vector drawables (experimental)
- Customize animations with the
AnimationSpec
parameter- Create physics-based animation with
spring
**** - Animate between start and end values with easing curve with
tween
**** - Animate to specific values at certain timings with
keyframes
**** - Repeat an animation with
repeatable
- Repeat an animation infinitely with
infiniteRepeatable
**** - Immediately snap to end value with
snap
****
- Create physics-based animation with
- Set a custom easing function
- Animate custom data types by converting to and from
AnimationVector
****
- Animation cheat sheet
- Semantics properties
- Merged and unmerged Semantics tree
- Inspecting the trees
- Merging behavior
- Adapting the Semantics tree
- Semantics
- Common use cases
- Consider minimum touch target sizes
- Add click labels
- Describe visual elements
- Merge elements
- Add custom actions
- Describe an element’s state
- Define headings
- Automated testing of accessibility properties
- Creating custom low-level composables
- Modify traversal order with
isTraversalGroup
andtraversalIndex
****- Group elements with
isTraversalGroup
**** - Further customize traversal order with traversalIndex
- Group elements with
- Definitions
- Different levels of abstraction
- Component support
- Add specific gestures to arbitrary composables with modifiers
- Add custom gesture to arbitrary composables with
pointerInput
modifier
- Event dispatching and hit-testing
- Event consumption
- Event propagation
- Test gestures
- Respond to tap or click
- Long-press to show a contextual context menu
- Dismiss a composable by tapping a scrim
- Double tap to zoom
- Scroll modifiers
- Scrollable modifier
- Nested scrolling
- Automatic nested scrolling
- Using the
nestedScroll
modifier
- Nested scrolling interop (Starting with Compose 1.2.0)
- A cooperating parent
View
containing a childComposeView
**** - A parent composable containing a child
AndroidView
**** - A non-cooperating parent
View
containing a childComposeView
****
- A cooperating parent
- Swiping
- Migrate
SwipeableState
toAnchoredDraggableState
****- Update your state holder
- Access the offset
- Migrate
Modifier.swipeable
toModifier.anchoredDraggable
****- Define anchors
- Define positional thresholds
- Define velocity thresholds
- Changes to the API surface
AnchoredDraggableState
****Modifier.anchoredDraggable
****
- Default focus traversal order
- Override one-dimensional traversal order
- Override two-dimensional traversal order
- Provide coherent navigation with focus groups
- Making a composable focusable
- Making a composable unfocusable
- Request keyboard focus with
FocusRequester
**** - Capture and release focus
- Precedence of focus modifiers
- Redirect focus upon entry or exit
- Change focus advancing direction
- Provide visual cues for easier focus visualization
- Implement advanced visual cues
- Understand the state of the focus
- Interactions
- Interaction state
- Consume and emit
Interaction
****- Consuming modifier example
- Producing modifier example
- Build components that consume and produce
- Work with
InteractionSource
**** - Example: Build component with custom interaction handling
- Create and apply a reusable custom effect with
Indication
****- Replace effect with an
Indication
- Build an advanced
Indication
with animated border
- Replace effect with an
- Behavior change
- Upgrade Material library version without migrating
- Migrate from
rememberRipple
toripple
****- Using a Material library
- Implementing custom design system
- Migrate from
RippleTheme
****- Temporarily opt out of behavior change
- Using
RippleTheme
to disable a ripple for a given component - Using
RippleTheme
to change the color/alpha of a ripple for a given component - Using
RippleTheme
to globally change all ripples in an application
- Migrate from
Indication
toIndicationNodeFactory
****- Passing around
Indication
**** - Creating
Indication
**** - Using
Indication
to create anIndicationInstance
****
- Passing around
- Layout Inspector
- Composition tracing
- Use
remember
to minimize expensive calculations - Use Lazy layout keys
- Use
derivedStateOf
to limit recompositions - Defer reads as long as possible
- Avoid backwards writes
- Immutable objects
- Mutable objects
- Implementation in Compose
- Functions
- Types
- Debug stability
- Fix stability issues
- Summary
- Layout Inspector
- Compose compiler reports
- Setup
- Run the task
- Make the class immutable
- Immutable collections
- Annotate with
Stable
orImmutable
****- Annotated classes in collections
- Stability configuration file
- Multiple modules
- Solution
- Not every composable should be skippable
- Audience
- Default arguments
- Higher-order functions and lambda expressions
- Trailing lambdas
- Scopes and receivers
- Delegated properties
- Destructuring data classes
- Singleton objects
- Type-safe builders and DSLs
- Kotlin coroutines
- Semantics
- Setup
- Testing APIs
- Finders
- Assertions
- Actions
- Matchers
- Synchronization
- Disabling automatic synchronization
- Idling resources
- Manual synchronization
- Waiting for conditions
- Common patterns
- Test in isolation
- Access the activity and resources after setting your own content
- Custom semantics properties
- Verify state restoration
- Debugging
- Interoperability with Espresso
- Interoperability with UiAutomator
- Build new screens with Compose
- Add new features in existing screens
- Build a library of common UI components
- Replace existing features with Compose
- Simple screens
- Mixed view and Compose screens
- Removing Fragments and Navigation component
ViewCompositionStrategy
forComposeView
****ComposeView
in Fragments- Multiple
ComposeView
instances in the same layout - Preview composables in Layout Editor
AndroidView
with view bindingAndroidView
in Lazy lists- Fragments in Compose
- Calling the Android framework from Compose
- Composition Locals
- Other interactions
- Case study: Broadcast receivers
- Migration steps
- Common use cases
- Item decorations
- Item animations
- Migration steps
- Common use cases
- Collapse and expand toolbars
- Drawers
- Snackbars
- Migration prerequisites
- Migration steps
- Common use cases
- Safe Args
- Retrieve complex data when navigating
- Limitations
- Incremental migration to Navigation Compose
- Transition animations
- Migrating your app's theme
- Navigation
- Test your mixed Compose/Views UI
- Integrating Compose with your existing app architecture
- Using a
ViewModel
in Compose - State source of truth
- Compose as the source of truth
- View system as the source of truth
- Using a
- Migrating shared UI
- Prioritize splitting state from presentation
- Promote encapsulated and reusable components
- Handling screen size changes
- Nested scrolling with Views
- Compose in
RecyclerView
**** WindowInsets
interop with Views
- Activity
- Activity Result
- Requesting runtime permissions
- Handling the system back button
ViewModel
****- Streams of data
- Asynchronous operations in Compose
- Navigation
- Hilt
- Hilt and Navigation
- Paging
- Maps
- APK size and build times
- APK size
- Build time
- Summary
- Runtime performance
- Smart recompositions
- Baseline Profiles
- Comparison with the View system
- Benchmark Compose
- Compose profile installation
- Define your
@Preview
****- Dimensions
- Dynamic color preview
- Use with different devices
- Locale
- Set background color
- System UI
- UI mode
LocalInspectionMode
- Interact with your
@Preview
****- Interactive mode
- Code navigation and composable outlines
- Run preview
- Copy
@Preview
render
- Multiple previews of the same
@Preview
annotation- Multipreview templates
- Create custom multipreview annotations
@Preview
and large data sets
- Limitations and best practices
- Previews limitations
- Previews and
ViewModels
****
- Annotation class
@Preview
****
- Live Edit
- Get started with Live Edit
- Troubleshoot Live Edit
- Limitations of Live Edit
- Frequently asked questions about Live Edit
- Live Edit of literals (deprecated)
- Apply Changes
- Live templates
- Gutter icons
- Deploy preview
- Color picker
- Image resource picker
- Get recomposition counts
- Compose semantics
- Set up for composition tracing
- Take a system trace
- Caveats
- APK size overhead
- Accurate timing
- Capture a trace from terminal
- Add dependencies
- Generate a record command
- Capture a trace
- Open the trace
- Capture a trace with Jetpack Macrobenchmark
- Prerequisites
- Install the Relay for Figma plugin
- Install the Relay for Android Studio plugin
- Install the Relay Gradle plugin
- Setup Figma access
- Download and setup the pre-configured project
- Running the pre-configured project
- Create a new Compose project
- Edit module-level Gradle build file
- Download pre-configured Figma file
- Create a component
- Create a UI Package
- Share with developer flow
- Import design from Figma
- Build & generate code
- Integrate component & run app
- Changes in Figma
- Save named version
- Update the component code
- Add a content parameter
- Save named version
- Update the component in Android Studio
- Starting point
- Copy Figma example
- Create a UI package
- Save named version
- Download Android Studio project
- Import into Android Studio
- Preview app & component
- Introduction
- Add parameters in Figma
- Save named version
- Update component in Android Studio
- Integrate into app
- Add handlers
- Save named version
- Update component in Android Studio
- Integrate into app
- Figma workflow
- Android Studio workflow
- UI Package & Generated Code
- UI Packages in Figma
- Create UI Package
- Add a summary
- Remove UI Packaging
- Parameter properties
- All layers
- Frame or group layer
- Text layer
- Image layer
- Adding parameters
- Rename parameters
- Remove parameters
- Example
- Checking error from "Share with developer" screen
- Best practices
- Check for errors and create named versions before sharing
- Sharing Figma Link
- Sharing all UI Packages in a page
- Sharing a specific UI package
- Sharing all UI Packages in a file
- Share all UI packages in a page with a specific version
- Advanced usage
- Import a UI Package
- UI Package import screen
- UI Package tool window
- Build your Android Project
- Update a UI Package
- UI Package
- Removing UI Packages
- Generated code folder structure
- Generated code structure
- Composables
- Translated Figma variants and parameters
- Read-only limitations
- Boolean properties
- Text properties
- Instance swap properties
- Variant properties
- Add nested instances and expose nested parameters
- Override properties of nested package instance
- Limitations
- Limitations
- Limitations
- Limitations
- Limitations
- Limitations
- Figma and translation limitations
- Supported Figma layer types
- Unsupported Figma layers and features
- Unsupported Figma properties
- Partially supported Figma layers and properties
- Multiple styles are dropped if passed into text parameter with one style
- Nested components with same variant properties as parent component fails to compile
- Font support
- Android Studio troubleshooting
- I received an error about converting SVG resources on Windows
- Updates are not imported into Android Studio
- I receive an error about SVG and Java Runtime when building
- I receive an error about fonts when building
- Updating resources outside ui-packages do not force a new build
- In Android Studio, undoing a deleted UI Package folder may fail
- Generated code or
ui-packages
folders are missing in Android project browser - App themes for child components are not updated
- UI Package name must start with letter
- Font padding in Compose does not match Figma
- Configuration files for custom translations
- Limitations
- Mapping file
- Generate a mapping file
- Mapping file name
- Mapping file contents
- Mapped variants
- Inset fundamentals
- Insets setup
- Compose APIs
- Padding modifiers
- Inset size modifiers
- Inset consumption
- Insets and Jetpack Compose phases
- Keyboard IME animations with
WindowInsets
**** - Inset support for Material 3 Components
- Inset handling composables
- Override default insets
- Default case
- Handle cutout information manually
- Best practices
- Test how your content renders with cutouts
- Add Glance dependencies
- Declare the
AppWidget
in the Manifest - Add the
AppWidgetProviderInfo
metadata - Define
GlanceAppWidget
**** - Create UI
- Launch an activity
- Launch a service
- Send a broadcast event
- Perform custom actions
- Run lambda actions
- Run ActionCallback
- Provide parameters to actions
- Manage
GlanceAppWidget
state- Use application state
- Update
GlanceAppWidget
****
- Use
Box
,Column
, andRow
**** - Use scrollable layouts
- Define the
SizeMode
****SizeMode.Single
****SizeMode.Responsive
****SizeMode.Exact
- Access resources
- Add compound buttons
- Add colors
- Add shapes