Lecture 2 - Jetpack Compose
Lecture 2 - Jetpack Compose
2
Declarative Paradigm Shift
With many imperative object-oriented UI toolkits, we
initialize the UI by instantiating a tree of widgets. We
often do this by inflating an XML layout file. Each
widget maintains its own internal state, and exposes
getter and setter methods that allow the app logic to
interact with the widget.
In Compose's declarative approach, widgets are
relatively stateless and do not expose setter or getter
functions. In fact, widgets are not exposed as
objects. You update the UI by calling the same
composable function with different arguments. This
makes it easy to provide state to architectural
patterns such as a ViewModel. Then, our
composables are responsible for transforming the
current application state into a UI every time the
observable data updates.
3
Declarative Paradigm Shift - Continued
When the user interacts with the UI, the UI raises events such as
onClick. Those events should notify the app logic, which can then
change the app's state. When the state changes, the composable
functions are called again with the new data. This causes the UI
elements to be redrawn--this process is called recomposition.
4
The three phases of a frame
Compose has three main phases:
1 Composition: What UI to show. Compose runs composable
functions and creates a description of your UI.
2 Layout: Where to place UI. This phase consists of two steps:
measurement and placement. Layout elements measure and place
themselves and any child elements in 2D coordinates, for each node
in the layout tree.
3 Drawing: How it renders. UI elements draw into a Canvas, usually a
device screen.
5
1. Composition
In the composition phase, the Compose runtime executes
composable functions and outputs a tree structure that
represents your UI. This UI tree consists of layout nodes that
contain all the information needed for the next phases.
6
1. Composition - Continued
A subsection looks like this:
7
2. Layout
In the layout phase, Compose uses the UI tree produced in the
composition phase as input. The collection of layout nodes
contain all the information needed to decide on each node's
size and location in 2D space.
8
3. Drawing
In the drawing phase, the tree is traversed again from top to
bottom, and each node draws itself on the screen in turn.
9
Phases During State change
10
Optimized State Changes
11
Lesson 1 – Basic Components
Lesson 1 - Jetpack Compose Basics
Jetpack Compose is built around composable functions
Using Compose, we can build your user interface by defining a
set of composable functions that take in data and emit UI
elements. A simple example is a Greeting widget, which takes
in a String and emits a Text widget which displays a greeting
message.
13
Define a composable function
// ...
To make a function import androidx.compose.runtime.Composable
composable, add the
class MainActivity : ComponentActivity() {
@Composable override fun onCreate(savedInstanceState: Bundle?) {
annotation. To try this out, super.onCreate(savedInstanceState)
setContent {
define a MessageCard MessageCard("Android")
}
function which is passed a }
name, and uses it to }
14
Preview your function in Android Studio
The @Preview import
annotation lets you androidx.compose.ui.tooling.preview.Pre
preview your view
Display a “Hello world!” text by adding a text element inside the
onCreate method import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text
17
Add multiple styles
18
Task – Text Widget
19
Buttons
Buttons are fundamental components that allow the user to trigger a defined
action. There are five types of buttons. The following table describes the
appearance of each of the five button types, as well as where you should
use them.
20
Buttons – Contd...
API surface
onClick: The function called when the user presses the button.
enabled: When false, this parameter causes the button to appear unavailable and inactive.
colors: An instance of ButtonColors that determines the colors used in the button.
contentPadding: The padding within the button.
21
Adding a Button
The following snippet demonstrates how to implement the
button component:
22
ImageBitmap vs ImageVector
A raster graphic format contains pixels: tiny individual squares that contain a color (made up
of red, green, blue, and alpha values). When placing a lot of pixels together, a very detailed
image can be formed, such as a photograph. A raster graphic has a fixed resolution (fixed
number of pixels). This means that when you increase the size of the image, it loses detail,
and pixelation can occur. Examples of raster graphic formats are JPEG, PNG, and WEBP.
Vector images, on the other hand, are scalable mathematical representations of a visual
element on screen. A vector is a set of commands describing how to draw the image on
screen- for instance, a line, point, or fill. When scaling a vector on screen, it will not lose
quality as the mathematical formula will maintain the relationship between the different
commands. A good example of ImageVector are the Material Symbols, as they can all be
defined with mathematical formulas.
For simple use cases, the same way in which painterResource() works for the
ImageBitmap class, it also works for ImageVectors, returning a VectorPainter as the result.
painterResource() handles the loading of VectorDrawables and BitmapDrawables into
VectorPainter and BitmapPainter respectively. To load a VectorDrawable into an image, use:
23
Images
Load an image from the disk using painterResource:
Load an image from the internet
24
Customize Images - Link
Images can be customized using properties on an Image composable
(contentScale, colorFilter). You can also apply the existing Modifiers to apply
different effects to your Image. Modifiers can be used on any Composable, not just
the Image composable, whereas contentScale and colorFilter are explicit parameters
on the Image composable.
Content scale
Specify a contentScale option to crop or change how an image is scaled inside its bounds.
By default, if you don't specify a contentScale option, ContentScale.Fit will be used.
25
Clip an Image to a shape
To make an image fit into a shape, use the built-in clip modifier.
To crop an image into a circle shape, use
Modifier.clip(CircleShape):
26
Color filter - Transform pixel colors of image
The Image composable has a colorFilter parameter that can change the
output of individual pixels of your image.
Tinting an image
Using ColorFilter.tint(color, blendMode) will apply a blend mode with the given color onto
your Image composable. ColorFilter.tint(color, blendMode) uses BlendMode.SrcIn to tint
content, meaning that the color supplied will be shown, where the image is displayed on
screen. This is useful for icons and vectors that need to be themed differently.
27
Task 2 - Images
28
Material Icons
The Icon composable is a convenient way to draw a single
color icon on screen that follows Material Design guidelines.
The Material Icon library also includes a set of predefined Icons
that can be used in Compose without needing to import an
SVG manually
29
Lesson 2 - Layouts
Lesson 2: Layouts
UI elements are hierarchical, with elements contained in other
elements. In Compose, you build a UI hierarchy by calling
composable functions from other composable functions.
31
Composable functions are the basic building block of Compose.
A composable function is a function emitting Unit that describes some part
of your UI.
The function takes some input and generates what's shown on the screen
Without guidance on how you want them arranged, Compose stacks the
text elements on top of each other, making them unreadable:
32
Standard layout components - Link
Use Column to place items vertically on the screen
Use Row to place items horizontally on the screen
33
Standard layout components - Link
Use Box to put elements on top of another
Often these building blocks are all we need. We can write your own composable
function to combine these layouts into a more elaborate layout that suits your app.
34
Alignment inside Row or Column
To set children's position within a Row, set the horizontalArrangement and
verticalAlignment arguments. For a Column, set the verticalArrangement
and horizontalAlignment arguments:
35
Alignment
There are nine alignment options that can be applied to child UI
elements:
36
Arrangement Horizontal Vertical
Arrangement is used to specify the arrangement Start Top
of child elements in "Column" and "Row" layouts
in the axis direction (horizontal and vertical). End Bottom
We have a set of predefined values for
horizontal and vertical arrangements: Center Center
SpaceEvenly SpaceEvenly
SpaceAround SpaceAround
SpaceBetween SpaceBetween
37
The "align" modifier
The align modifier allows us to set arrangement of children
inside the Box Scope.
Box(
modifier = Modifier.size(height = 120.dp, width = 300.dp)
){
Text(text = "TopStart", modifier = Modifier.align(Alignment.TopStart))
Text(text = "TopCenter", modifier = Modifier.align(Alignment.TopCenter))
Text(text = "TopEnd", modifier = Modifier.align(Alignment.TopEnd))
The "ConstraintLayout" layout positions children according to the constraints
between them. It's similar to the available "ConstraintLayout" for Android
development
Create references for each composable in the ConstraintLayout using the createRefs() or
createRefFor()
Constraints are provided using the constrainAs() modifier, which takes the reference as a
parameter and lets you specify its constraints in the body lambda.
Constraints are specified using linkTo() or other helpful methods.
parent is an existing reference that can be used to specify constraints towards the
ConstraintLayout composable itself.
39
Example
40
Compose Modifiers
Modifiers allow you to decorate or augment a composable. Modifiers let you
do these sorts of things:
Change the composable's size, layout, behavior, and appearance
Add information, like accessibility labels
Process user input
Add high-level interactions, like making an element clickable, scrollable, draggable, or
zoomable
41
Built-in Modifiers
Jetpack Compose provides a list of built-in modifiers to help you decorate or
augment a composable. Here are some common modifiers you'll use to adjust your
layouts.
padding and size
Offset
42
Lesson 3 – Important Composables
Lesson 3 – Important Composables
Surface
Scaffold
AppBar (topBar / bottomBar)
Floating Action Buttons
Card
Chip
Dialog
SnackBar
44
Surface
Surface is a basic building block for displaying content and can be used to
wrap other composable to provide a background color, elevation, padding,
and other layout properties.
45
Scaffold
In Material Design, a scaffold is a fundamental structure that
provides a standardized platform for complex user interfaces. It
holds together different parts of the UI, such as app bars and
floating action buttons, giving apps a coherent look and feel.
The Scaffold composable provides a straightforward API you can
use to quickly assemble your app's structure according to Material
Design guidelines. Scaffold accepts several composables as
parameters. Among these are the following:
topBar: The app bar across the top of the screen.
bottomBar: The app bar across the bottom of the screen.
floatingActionButton: A button that hovers over the bottom-right corner
of the screen that you can use to expose key actions.
46
Scaffold
47
App bars
48
App Bar
49
API surface
The various composables that allow you to implement the four
different top app bars are quite similar. They share several key
parameters:
title: The text that appears across the app bar.
navigationIcon: The primary icon for navigation. Appears on the left of
the app bar.
actions: Icons that provide the user access to key actions. They
appear on the right of the app bar.
scrollBehavior: Determines how the top app bar responds to scrolling
of the scaffold's inner content.
colors: Determines how the app bar appears.
50
Code
51
Centered – App Bar
52
Floating action button
A Floating Action Button (FAB) is a high-emphasis button that lets the user perform a
primary action in an application. It promotes a single, focused action that is the most
common pathway a user might take and is typically found anchored to the bottom
right of the screen.
In Material Design, there are four types of FAB:
FAB: A floating action button of ordinary size.
Small FAB: A smaller floating action button.
Large FAB: A larger floating action button.
Extended FAB: A floating action button that c ontains more than just an icon
53
Floating Action Button – Api Interface
Although there are several composables we can use to create floating action buttons
consistent with Material Design, their parameters don't differ greatly. Among the key
parameters are the following:
onClick: The function called when the user presses the button.
containerColor: The color of the button.
contentColor: The color of the icon.
54
Card
The Card composable acts as a Material Design container for your UI. Cards
typically present a single coherent piece of content. The following are some
examples of where you might use a card:
A product in a shopping app.
A news story in a news app.
A message in a communications app.
55
Card - Continued
Some key parameters to note are the following:
elevation: Adds a shadow to the component that makes it appear elevated above the
background.
colors: Uses the CardColors type to set the default color of both the container and any
children.
enabled: If you pass false for this parameter, the card appears as disabled and does not
respond to user input.
onClick: Ordinarily, a Card does not accept click events. As such, the primary overload
you would like to note is that which defines an onClick parameter. You should use this
overload if you would like your implementation of Card to respond to presses from the
user.
56
Card – Filled Example
57
Card - Elevated
58
Chip
The Chip component is a compact, interactive UI element. It represents complex entities like a
contact or tag, often with an icon and label. It can be checkable, dismissible, or clickable.
The four types of chips and where you might use them are as follows:
Assist: Guides the user during a task. Often appears as a temporary UI element in response to user
input.
Filter: Allows users to refine content from a set of options. They can be selected or deselected, and
may include a checkmark icon when selected.
Input: Represents user-provided information, such as selections in a menu. They can contain an icon
and text, and provide an 'X' for removal.
Suggestion: Provides recommendations to the user based on their recent activity or input. Typically
appear beneath an input field to prompt user actions.
59
Chip – Api Interface
There are four composables that correspond to the four types of chips. The following
sections outline these composables and their differences in detail. However, they
share the following parameters:
label: The string that appears on the chip.
icon: The icon displayed at the start of the chip. Some of the specific composables have a separate
leadingIcon and trailingIcon parameter.
onClick: The lambda that the chip calls when the user presses it.
60
Canvas
61
Task - 3
62
Dialogs
The Dialog component displays pop up messages or requests user input on a layer
above the main app content. It creates an interruptive UI experience to capture user
attention.
Among the use cases for a dialog are the following:
Confirming user action, such as when deleting a file.
Requesting user input, such as in a to-do list app.
Presenting a list of options for user selection, like choosing a country in a profile setup.
63
Alert dialog
The AlertDialog composable provides a convenient API for creating a Material Design themed
dialog. AlertDialog has specific parameters for handling particular elements of the dialog. Among them are
the following:
title: The text that appears along the top of the dialog.
text: The text that appears centered within the dialog.
icon: The graphic that appears at the top of the dialog.
onDismissRequest: The function called when the user dismisses the dialog, such as by tapping outside of
it.
dismissButton: A composable that serves as the dismiss button.
confirmButton: A composable that serves as the confirm button.
64
Alert Dialog
65
Lesson 4 – State Management
67