SlideShare a Scribd company logo
1 of 120
Download to read offline
This work is licensed under the Apache 2.0 License
Jetpack Compose
for Android Developers
This work is licensed under the Apache 2.0 License
Firstname Lastname
Company and Title
Firstname Lastname
Company and Title
Camp Counselors
This work is licensed under the Apache 2.0 License
● Thinking in Compose
● Composable functions
● Compose toolkit
● Tooling
Agenda
This work is licensed under the Apache 2.0 License
Thinking in
Compose
This work is licensed under the Apache 2.0 License
Construct UI by
describing what,
not how.
This work is licensed under the Apache 2.0 License
goo.gle/compose-samples
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
Survey answer
Image Text Radio button
This work is licensed under the Apache 2.0 License
<LinearLayout android:orientation=“horizontal” >
<ImageView
android:id=”@+id/answer_image” ... />
<TextView
android:id=”@+id/answer_text” ... />
<RadioButton
android:id=”@+id/answer_radio_button” ... />
</LinearLayout>
<!-- survey_answer.xml -->
This work is licensed under the Apache 2.0 License
class SurveyQuestionActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val image = findViewById(R.id.answer_image)
val text = findViewById(R.id.answer_text)
val radioButton =
findViewById(R.id.answer_radio_button)
// ...
}
}
// SurveyQuestionActivity.kt
This work is licensed under the Apache 2.0 License
class SurveyQuestionActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
// ...
image.setImage(...)
text.setText(...)
// ...
}
}
// SurveyQuestionActivity.kt
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
Survey answer
Image Text Radio button
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Row {
Image(answer.image)
Text(answer.text)
RadioButton(false, onClick = { /* … */ })
}
}
// SurveyAnswer.kt
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Row {
Image(answer.image)
Text(answer.text)
RadioButton(false, onClick = { /* … */ })
}
}
// SurveyAnswer.kt
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Row {
Image(answer.image)
Text(answer.text)
RadioButton(false, onClick = { /* … */ })
}
}
// SurveyAnswer.kt
This work is licensed under the Apache 2.0 License
Construct UI by
describing what,
not how.
This work is licensed under the Apache 2.0 License
Event handler
UI element
onClick()
This work is licensed under the Apache 2.0 License
UI
State
This work is licensed under the Apache 2.0 License
UI 2
State 2
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Row {
/ * ... */
var selected: Boolean = // ...
RadioButton(selected, onClick = { /* … */ })
}
}
// SurveyAnswer.kt
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Row {
/ * ... */
var selected: Boolean = // ...
RadioButton(selected, onClick = {
selected = !selected
})
}
}
// SurveyAnswer.kt
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Row {
/ * ... */
var selected: Boolean = // ...
RadioButton(selected, onClick = {
selected = !selected
})
}
}
// SurveyAnswer.kt
Describe what, not how
UI elements are functions
State controls UI
Events control State
1
2
3
4
This work is licensed under the Apache 2.0 License
Composable
functions
This work is licensed under the Apache 2.0 License
goo.gle/compose-samples
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
// SurveyAnswer.kt
@Composable
fun SurveyAnswer(answer: Answer) {
Row {
Image(answer.image)
Text(answer.text)
RadioButton(false, onClick = { /* … */ })
}
}
This work is licensed under the Apache 2.0 License
// SurveyAnswer.kt
@Composable
fun SurveyAnswer(answer: Answer) {
Row {
Image(answer.image)
Text(answer.text)
RadioButton(false, onClick = { /* … */ })
}
}
This work is licensed under the Apache 2.0 License
// SurveyAnswer.kt
@Composable
fun SurveyAnswer(answer: Answer) { /* … */ }
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
Column {
answers.forEach { answer ->
SurveyAnswer(answer = answer)
}
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
Column {
answers.forEach { answer ->
SurveyAnswer(answer = answer)
}
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
Column {
answers.forEach { answer ->
SurveyAnswer(answer = answer)
}
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
Column {
answers.forEach { answer ->
// Can’t do this!!
val answer = SurveyAnswer(answer = answer)
}
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
Column {
answers.forEach { answer ->
SurveyAnswer(answer = answer)
}
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
Column {
if (answers.isEmpty()) {
Text(“There are no answers to choose from!”)
} else {
answers.forEach { answer ->
SurveyAnswer(answer = answer)
}
}
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
// Don’t do this! There shouldn’t be side-effects
SurveyApp.didShowSingleChoiceQuestion = true
Column {
if (answers.isEmpty()) { /* ... */ }
else { /* ... */ }
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
// Fast and no side-effects
Column {
if (answers.isEmpty()) { /* ... */ }
else { /* ... */ }
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
Column {
answers.forEach { answer ->
SurveyAnswer(answer = answer)
}
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = false,
)
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = false,
)
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = false,
)
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
var selectedAnswer: Answer? = null
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = false,
)
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
var selectedAnswer: Answer? = null
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = false,
)
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
var selectedAnswer: MutableState<Answer?> =
mutableStateOf(null)
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = false,
)
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
var selectedAnswer: MutableState<Answer?> =
mutableStateOf(null)
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = false,
)
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
var selectedAnswer: MutableState<Answer?> =
mutableStateOf(null)
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = (selectedAnswer.state == answer),
)
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
var selectedAnswer: MutableState<Answer?> =
remember { mutableStateOf(null) }
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = (selectedAnswer.state == answer),
)
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
var selectedAnswer: MutableState<Answer?> =
rememberSaveable { mutableStateOf(null) }
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = (selectedAnswer.state == answer),
)
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
var selectedAnswer: Answer? by
rememberSaveable { mutableStateOf(null) }
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = (selectedAnswer.state == answer),
)
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
var selectedAnswer: Answer? by
rememberSaveable { mutableStateOf(null) }
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = (selectedAnswer == answer),
)
}
}
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
var selectedAnswer: Answer? by
rememberSaveable { mutableStateOf(null) }
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = (selectedAnswer == answer),
onAnswerSelected = { answer -> selectedAnswer = answer }
)
}
}
This work is licensed under the Apache 2.0 License
Event handler
UI element
event
state
Events change State
This work is licensed under the Apache 2.0 License
Event handler
UI element
onAnswerSelected
answer
Events change State
This work is licensed under the Apache 2.0 License
// SingleChoiceQuestion.kt
@Composable
fun SingleChoiceQuestion(answers: List<Answer>) {
val selectedAnswer: Answer? by
rememberSaveable { mutableStateOf<Answer>(null) }
answers.forEach { answer ->
SurveyAnswer(
answer = answer,
isSelected = (selectedAnswer == answer),
onAnswerSelected = { answer -> selectedAnswer = answer }
)
}
}
This work is licensed under the Apache 2.0 License
Composable
functions can
execute in any order.
This work is licensed under the Apache 2.0 License
// ButtonRow.kt
@Composable
fun ButtonRow() {
MyFancyNavigation {
StartScreen()
MiddleScreen()
EndScreen()
}
}
This work is licensed under the Apache 2.0 License
Composable
functions can run
in parallel.
This work is licensed under the Apache 2.0 License
@Composable
fun ListComposable(myList: List<String>) {
Row(horizontalArrangement = Arrangement.SpaceBetween) {
Column {
for (item in myList) {
Text("Item: $item")
}
}
Text("Count: ${myList.size}")
}
}
// ListComposable.kt
This work is licensed under the Apache 2.0 License
@Composable
fun ListWithBug(myList: List<String>) {
var items = 0
Row(horizontalArrangement = Arrangement.SpaceBetween) {
Column {
for (item in myList) {
Text("Item: $item”)
items++ // Avoid! Side-effect of the column recomposing.
}
}
Text("Count: $items")
}
}
// ListComposable.kt
This work is licensed under the Apache 2.0 License
Recomposition skips
as much as possible.
This work is licensed under the Apache 2.0 License
@Composable
fun GreetingScreen(name: String) {
Column {
Header()
Greeting(name = name)
Footer()
}
}
// GreenScreen.kt
This work is licensed under the Apache 2.0 License
Recomposition is
optimistic.
This work is licensed under the Apache 2.0 License
Composable
functions might run
frequently.
This work is licensed under the Apache 2.0 License
Summary
Create composables using the @Composable annotation
It’s quick & easy to create composables
Composables accept parameters
Use MutableState and remember
Composables should be side-effect free
This work is licensed under the Apache 2.0 License
Composables can:
Execute in any order
Run in parallel
Be skipped
Run frequently
1
2
3
4
This work is licensed under the Apache 2.0 License
Compose Toolkit
This work is licensed under the Apache 2.0 License
goo.gle/compose-samples
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
MaterialTheme(
colorScheme = MyAppsColorScheme,
typography = MyAppsTypography,
shapes = MyAppsShapes
) {
// Content goes here
}
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
Scaffold(
topBar = { SmallTopAppBar(/* ... */) },
floatingActionButtonPosition = FabPosition.End,
floatingActionButton = {
FloatingActionButton(/* ... */)
},
content = { /* ... */ }
)
This work is licensed under the Apache 2.0 License
SurveyTopAppBar
SurveyBottomBar
Question
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
Surface {
Text("Hello Compose")
}
Hello Compose
This work is licensed under the Apache 2.0 License
Surface(
color = MaterialTheme.colorScheme.primary,
) {
Text("Hello Compose")
}
Hello Compose
This work is licensed under the Apache 2.0 License
Surface(
color = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(8.dp),
) {
Text("Hello Compose")
}
Hello Compose
This work is licensed under the Apache 2.0 License
Surface(
color = MaterialTheme.colorScheme.surface,
shape = RoundedCornerShape(8.dp),
border = BorderStroke(2.dp,
MaterialTheme.colorScheme.outline
)
) {
Text("Hello Compose")
}
Hello Compose
This work is licensed under the Apache 2.0 License
Surface(
color = MaterialTheme.colorScheme.surface,
shape = RoundedCornerShape(8.dp),
border = BorderStroke(2.dp,
MaterialTheme.colorScheme.surfaceVariant
),
shadowElevation = 8.dp,
tonalElevation = 8.dp,
) {
Text("Hello Compose")
}
Hello Compose
This work is licensed under the Apache 2.0 License
This work is licensed under the Apache 2.0 License
goo.gle/compose-material-ref
m3.material.io
This work is licensed under the Apache 2.0 License
Standard layouts
This work is licensed under the Apache 2.0 License
Row {
Component1()
Component2()
Component3()
} 1 2 3
Row
This work is licensed under the Apache 2.0 License
1
2
3
Column
Column {
Component1()
Component2()
Component3()
}
This work is licensed under the Apache 2.0 License
2
1
3
Box
Box {
Component1()
Component2()
Component3()
}
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Row {
Image(answer.image)
Text(answer.text)
RadioButton(/* … */)
}
}
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Row(
verticalAlignment =
Alignment.CenterVertically
) {
/* ... */
}
}
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Row(
verticalAlignment =
Alignment.CenterVertically,
horizontalArrangement =
Arrangement.SpaceBetween
) {
/* ... */
}
}
goo.gle/compose-layouts-docs
This work is licensed under the Apache 2.0 License
Modifiers
This work is licensed under the Apache 2.0 License
Text("Hello
Compose")
Hello
Compose
This work is licensed under the Apache 2.0 License
Text(
"Hello Compose!",
Modifier.background(Color.Magenta)
)
Hello
Compose
This work is licensed under the Apache 2.0 License
Text(
"Hello Compose!",
Modifier.background(Color.Magenta)
.size(200.dp, 30.dp)
)
Hello Compose
This work is licensed under the Apache 2.0 License
Text(
"Hello Compose!",
Modifier.background(Color.Magenta)
.size(200.dp, 30.dp)
.padding(5.dp)
)
Hello Compose
This work is licensed under the Apache 2.0 License
Text(
"Hello Compose!",
Modifier.background(Color.Magenta)
.size(200.dp, 30.dp)
.padding(5.dp)
.alpha(0.5f)
)
Hello Compose
This work is licensed under the Apache 2.0 License
Text(
"Hello Compose!",
Modifier.background(Color.Magenta)
.size(200.dp, 30.dp)
.padding(5.dp)
.alpha(0.5f)
.clickable {
// Called when Text clicked
}
)
Hello Compose
This work is licensed under the Apache 2.0 License
Box(Modifier.size(150.dp)) {
Text("Hello Compose")
}
Hello Compose
This work is licensed under the Apache 2.0 License
Box(Modifier.size(150.dp)) {
Text(
"Hello Compose!",
Modifier.align(
Alignment.BottomEnd
)
)
} Hello Compose
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Row(...) {
Image(answer.image)
Text(answer.text)
RadioButton(/* … */)
}
}
Desired
Current
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Row(
Modifier.fillMaxWidth(),
/* ... */
) {
Image(answer.image)
Text(answer.text)
RadioButton(/* ... */)
}
}
Desired
Current
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Row(
Modifier.fillMaxWidth()
.padding(16.dp),
/* ... */
) {
Image(answer.image)
Text(answer.text)
RadioButton(/* ... */)
}
}
Desired
Current
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Surface(
border = BorderStroke(
1.dp,
MaterialTheme.colorScheme.outline
),
shape = MaterialTheme.shapes.small
) {
Row(/* ... */) { }
}
}
Desired
Current
goo.gle/compose-modifiers
goo.gle/compose-modifiers-list
This work is licensed under the Apache 2.0 License
@Composable
fun SurveyAnswer(answer: Answer) {
Surface(
border = BorderStroke(
1.dp,
MaterialTheme.colorScheme.outline
),
shape = MaterialTheme.shapes.small
) {
Row(Modifier.fillMaxWidth().padding(16.dp)) {
Image(answer.image)
Text(answer.text)
RadioButton(/* … */)
}
}
}
This work is licensed under the Apache 2.0 License
Compose Tooling
This work is licensed under the Apache 2.0 License
Live demo!

More Related Content

Similar to Jetpack Compose Recap Session.pdf

Compose Camp Session 2
Compose Camp Session 2Compose Camp Session 2
Compose Camp Session 2AkshatBajpai12
 
Android Study Jam Prior Prog S-2
Android Study Jam Prior Prog S-2Android Study Jam Prior Prog S-2
Android Study Jam Prior Prog S-2DSCIGDTUW
 
-Kotlin_Camp_Unit2.pptx
-Kotlin_Camp_Unit2.pptx-Kotlin_Camp_Unit2.pptx
-Kotlin_Camp_Unit2.pptxRishiGandhi19
 
Compose Camp S1.pptx
Compose Camp S1.pptxCompose Camp S1.pptx
Compose Camp S1.pptxGDSCSIT
 
Day3New GDSC.pptx
Day3New GDSC.pptxDay3New GDSC.pptx
Day3New GDSC.pptxGDSCICOER
 
Compose Camp Slide Session 1
Compose Camp Slide Session 1Compose Camp Slide Session 1
Compose Camp Slide Session 1AkshatBajpai12
 
Android Study Jams - New to Programming [27th december]
Android Study Jams - New to Programming [27th december]Android Study Jams - New to Programming [27th december]
Android Study Jams - New to Programming [27th december]PragatiVerma31
 
Android Development | Compose Camp Day 1 | GDSC SEC Sasaram.pdf
Android Development | Compose Camp Day 1 | GDSC SEC Sasaram.pdfAndroid Development | Compose Camp Day 1 | GDSC SEC Sasaram.pdf
Android Development | Compose Camp Day 1 | GDSC SEC Sasaram.pdfShivamShrey1
 
Compose Camp Day 1.pdf
Compose Camp Day 1.pdfCompose Camp Day 1.pdf
Compose Camp Day 1.pdfShivamShrey1
 
GDSC_day_1.pptx
GDSC_day_1.pptxGDSC_day_1.pptx
GDSC_day_1.pptxGDSCICOER
 
Prior programming experience track
Prior programming experience trackPrior programming experience track
Prior programming experience trackAshwinRaj57
 
Session-1 edited.pptx
Session-1 edited.pptxSession-1 edited.pptx
Session-1 edited.pptxscienceTech11
 

Similar to Jetpack Compose Recap Session.pdf (20)

day1.docx
day1.docxday1.docx
day1.docx
 
Compose Camp Session 2
Compose Camp Session 2Compose Camp Session 2
Compose Camp Session 2
 
Android Study Jam Prior Prog S-2
Android Study Jam Prior Prog S-2Android Study Jam Prior Prog S-2
Android Study Jam Prior Prog S-2
 
-Kotlin_Camp_Unit2.pptx
-Kotlin_Camp_Unit2.pptx-Kotlin_Camp_Unit2.pptx
-Kotlin_Camp_Unit2.pptx
 
-Kotlin Camp Unit2.pptx
-Kotlin Camp Unit2.pptx-Kotlin Camp Unit2.pptx
-Kotlin Camp Unit2.pptx
 
Compose Camp S1.pptx
Compose Camp S1.pptxCompose Camp S1.pptx
Compose Camp S1.pptx
 
Compose Camp 2.pdf
Compose Camp 2.pdfCompose Camp 2.pdf
Compose Camp 2.pdf
 
Compose Camp.pdf
Compose Camp.pdfCompose Camp.pdf
Compose Camp.pdf
 
Day3New GDSC.pptx
Day3New GDSC.pptxDay3New GDSC.pptx
Day3New GDSC.pptx
 
Compose Camp Slide Session 1
Compose Camp Slide Session 1Compose Camp Slide Session 1
Compose Camp Slide Session 1
 
Android Study Jams - New to Programming [27th december]
Android Study Jams - New to Programming [27th december]Android Study Jams - New to Programming [27th december]
Android Study Jams - New to Programming [27th december]
 
Android Development | Compose Camp Day 1 | GDSC SEC Sasaram.pdf
Android Development | Compose Camp Day 1 | GDSC SEC Sasaram.pdfAndroid Development | Compose Camp Day 1 | GDSC SEC Sasaram.pdf
Android Development | Compose Camp Day 1 | GDSC SEC Sasaram.pdf
 
Compose Camp Day 1.pdf
Compose Camp Day 1.pdfCompose Camp Day 1.pdf
Compose Camp Day 1.pdf
 
GDSC_day_1.pptx
GDSC_day_1.pptxGDSC_day_1.pptx
GDSC_day_1.pptx
 
Prior programming experience track
Prior programming experience trackPrior programming experience track
Prior programming experience track
 
Session-1 edited.pptx
Session-1 edited.pptxSession-1 edited.pptx
Session-1 edited.pptx
 
Kotlin Fundamentals.pptx
Kotlin Fundamentals.pptxKotlin Fundamentals.pptx
Kotlin Fundamentals.pptx
 
Session-1.pptx
Session-1.pptxSession-1.pptx
Session-1.pptx
 
Compose Camp
Compose Camp Compose Camp
Compose Camp
 
Compose Camp Day 2.pptx
Compose Camp Day 2.pptxCompose Camp Day 2.pptx
Compose Camp Day 2.pptx
 

Recently uploaded

How to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptxHow to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptxCeline George
 
Micro-Scholarship, What it is, How can it help me.pdf
Micro-Scholarship, What it is, How can it help me.pdfMicro-Scholarship, What it is, How can it help me.pdf
Micro-Scholarship, What it is, How can it help me.pdfPoh-Sun Goh
 
The basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptxThe basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptxheathfieldcps1
 
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptxBasic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptxDenish Jangid
 
Wellbeing inclusion and digital dystopias.pptx
Wellbeing inclusion and digital dystopias.pptxWellbeing inclusion and digital dystopias.pptx
Wellbeing inclusion and digital dystopias.pptxJisc
 
Introduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsIntroduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsTechSoup
 
Understanding Accommodations and Modifications
Understanding  Accommodations and ModificationsUnderstanding  Accommodations and Modifications
Understanding Accommodations and ModificationsMJDuyan
 
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdfUGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdfNirmal Dwivedi
 
REMIFENTANIL: An Ultra short acting opioid.pptx
REMIFENTANIL: An Ultra short acting opioid.pptxREMIFENTANIL: An Ultra short acting opioid.pptx
REMIFENTANIL: An Ultra short acting opioid.pptxDr. Ravikiran H M Gowda
 
Google Gemini An AI Revolution in Education.pptx
Google Gemini An AI Revolution in Education.pptxGoogle Gemini An AI Revolution in Education.pptx
Google Gemini An AI Revolution in Education.pptxDr. Sarita Anand
 
Towards a code of practice for AI in AT.pptx
Towards a code of practice for AI in AT.pptxTowards a code of practice for AI in AT.pptx
Towards a code of practice for AI in AT.pptxJisc
 
Key note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfKey note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfAdmir Softic
 
Kodo Millet PPT made by Ghanshyam bairwa college of Agriculture kumher bhara...
Kodo Millet  PPT made by Ghanshyam bairwa college of Agriculture kumher bhara...Kodo Millet  PPT made by Ghanshyam bairwa college of Agriculture kumher bhara...
Kodo Millet PPT made by Ghanshyam bairwa college of Agriculture kumher bhara...pradhanghanshyam7136
 
Holdier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfHoldier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfagholdier
 
Interdisciplinary_Insights_Data_Collection_Methods.pptx
Interdisciplinary_Insights_Data_Collection_Methods.pptxInterdisciplinary_Insights_Data_Collection_Methods.pptx
Interdisciplinary_Insights_Data_Collection_Methods.pptxPooja Bhuva
 
How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17Celine George
 
Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...
Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...
Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...Pooja Bhuva
 
Application orientated numerical on hev.ppt
Application orientated numerical on hev.pptApplication orientated numerical on hev.ppt
Application orientated numerical on hev.pptRamjanShidvankar
 
How to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POSHow to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POSCeline George
 
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdf
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdfUnit 3 Emotional Intelligence and Spiritual Intelligence.pdf
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdfDr Vijay Vishwakarma
 

Recently uploaded (20)

How to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptxHow to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptx
 
Micro-Scholarship, What it is, How can it help me.pdf
Micro-Scholarship, What it is, How can it help me.pdfMicro-Scholarship, What it is, How can it help me.pdf
Micro-Scholarship, What it is, How can it help me.pdf
 
The basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptxThe basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptx
 
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptxBasic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
 
Wellbeing inclusion and digital dystopias.pptx
Wellbeing inclusion and digital dystopias.pptxWellbeing inclusion and digital dystopias.pptx
Wellbeing inclusion and digital dystopias.pptx
 
Introduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsIntroduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The Basics
 
Understanding Accommodations and Modifications
Understanding  Accommodations and ModificationsUnderstanding  Accommodations and Modifications
Understanding Accommodations and Modifications
 
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdfUGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
 
REMIFENTANIL: An Ultra short acting opioid.pptx
REMIFENTANIL: An Ultra short acting opioid.pptxREMIFENTANIL: An Ultra short acting opioid.pptx
REMIFENTANIL: An Ultra short acting opioid.pptx
 
Google Gemini An AI Revolution in Education.pptx
Google Gemini An AI Revolution in Education.pptxGoogle Gemini An AI Revolution in Education.pptx
Google Gemini An AI Revolution in Education.pptx
 
Towards a code of practice for AI in AT.pptx
Towards a code of practice for AI in AT.pptxTowards a code of practice for AI in AT.pptx
Towards a code of practice for AI in AT.pptx
 
Key note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfKey note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdf
 
Kodo Millet PPT made by Ghanshyam bairwa college of Agriculture kumher bhara...
Kodo Millet  PPT made by Ghanshyam bairwa college of Agriculture kumher bhara...Kodo Millet  PPT made by Ghanshyam bairwa college of Agriculture kumher bhara...
Kodo Millet PPT made by Ghanshyam bairwa college of Agriculture kumher bhara...
 
Holdier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfHoldier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdf
 
Interdisciplinary_Insights_Data_Collection_Methods.pptx
Interdisciplinary_Insights_Data_Collection_Methods.pptxInterdisciplinary_Insights_Data_Collection_Methods.pptx
Interdisciplinary_Insights_Data_Collection_Methods.pptx
 
How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17
 
Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...
Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...
Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...
 
Application orientated numerical on hev.ppt
Application orientated numerical on hev.pptApplication orientated numerical on hev.ppt
Application orientated numerical on hev.ppt
 
How to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POSHow to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POS
 
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdf
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdfUnit 3 Emotional Intelligence and Spiritual Intelligence.pdf
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdf
 

Jetpack Compose Recap Session.pdf

  • 1. This work is licensed under the Apache 2.0 License Jetpack Compose for Android Developers
  • 2. This work is licensed under the Apache 2.0 License Firstname Lastname Company and Title Firstname Lastname Company and Title Camp Counselors
  • 3. This work is licensed under the Apache 2.0 License ● Thinking in Compose ● Composable functions ● Compose toolkit ● Tooling Agenda
  • 4. This work is licensed under the Apache 2.0 License Thinking in Compose
  • 5. This work is licensed under the Apache 2.0 License Construct UI by describing what, not how.
  • 6. This work is licensed under the Apache 2.0 License goo.gle/compose-samples
  • 7. This work is licensed under the Apache 2.0 License
  • 8. This work is licensed under the Apache 2.0 License Survey answer Image Text Radio button
  • 9. This work is licensed under the Apache 2.0 License <LinearLayout android:orientation=“horizontal” > <ImageView android:id=”@+id/answer_image” ... /> <TextView android:id=”@+id/answer_text” ... /> <RadioButton android:id=”@+id/answer_radio_button” ... /> </LinearLayout> <!-- survey_answer.xml -->
  • 10. This work is licensed under the Apache 2.0 License class SurveyQuestionActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val image = findViewById(R.id.answer_image) val text = findViewById(R.id.answer_text) val radioButton = findViewById(R.id.answer_radio_button) // ... } } // SurveyQuestionActivity.kt
  • 11. This work is licensed under the Apache 2.0 License class SurveyQuestionActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { // ... image.setImage(...) text.setText(...) // ... } } // SurveyQuestionActivity.kt
  • 12. This work is licensed under the Apache 2.0 License
  • 13. This work is licensed under the Apache 2.0 License
  • 14. This work is licensed under the Apache 2.0 License
  • 15. This work is licensed under the Apache 2.0 License
  • 16. This work is licensed under the Apache 2.0 License
  • 17. This work is licensed under the Apache 2.0 License Survey answer Image Text Radio button
  • 18. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Row { Image(answer.image) Text(answer.text) RadioButton(false, onClick = { /* … */ }) } } // SurveyAnswer.kt
  • 19. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Row { Image(answer.image) Text(answer.text) RadioButton(false, onClick = { /* … */ }) } } // SurveyAnswer.kt
  • 20. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Row { Image(answer.image) Text(answer.text) RadioButton(false, onClick = { /* … */ }) } } // SurveyAnswer.kt
  • 21. This work is licensed under the Apache 2.0 License Construct UI by describing what, not how.
  • 22. This work is licensed under the Apache 2.0 License Event handler UI element onClick()
  • 23. This work is licensed under the Apache 2.0 License UI State
  • 24. This work is licensed under the Apache 2.0 License UI 2 State 2
  • 25. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Row { / * ... */ var selected: Boolean = // ... RadioButton(selected, onClick = { /* … */ }) } } // SurveyAnswer.kt
  • 26. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Row { / * ... */ var selected: Boolean = // ... RadioButton(selected, onClick = { selected = !selected }) } } // SurveyAnswer.kt
  • 27. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Row { / * ... */ var selected: Boolean = // ... RadioButton(selected, onClick = { selected = !selected }) } } // SurveyAnswer.kt
  • 28. Describe what, not how UI elements are functions State controls UI Events control State 1 2 3 4
  • 29. This work is licensed under the Apache 2.0 License Composable functions
  • 30. This work is licensed under the Apache 2.0 License goo.gle/compose-samples
  • 31. This work is licensed under the Apache 2.0 License
  • 32. This work is licensed under the Apache 2.0 License // SurveyAnswer.kt @Composable fun SurveyAnswer(answer: Answer) { Row { Image(answer.image) Text(answer.text) RadioButton(false, onClick = { /* … */ }) } }
  • 33. This work is licensed under the Apache 2.0 License // SurveyAnswer.kt @Composable fun SurveyAnswer(answer: Answer) { Row { Image(answer.image) Text(answer.text) RadioButton(false, onClick = { /* … */ }) } }
  • 34. This work is licensed under the Apache 2.0 License // SurveyAnswer.kt @Composable fun SurveyAnswer(answer: Answer) { /* … */ } @Composable fun SingleChoiceQuestion(answers: List<Answer>) { Column { answers.forEach { answer -> SurveyAnswer(answer = answer) } } }
  • 35. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { Column { answers.forEach { answer -> SurveyAnswer(answer = answer) } } }
  • 36. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { Column { answers.forEach { answer -> SurveyAnswer(answer = answer) } } }
  • 37. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt
  • 38. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { Column { answers.forEach { answer -> // Can’t do this!! val answer = SurveyAnswer(answer = answer) } } }
  • 39. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { Column { answers.forEach { answer -> SurveyAnswer(answer = answer) } } }
  • 40. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { Column { if (answers.isEmpty()) { Text(“There are no answers to choose from!”) } else { answers.forEach { answer -> SurveyAnswer(answer = answer) } } } }
  • 41. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { // Don’t do this! There shouldn’t be side-effects SurveyApp.didShowSingleChoiceQuestion = true Column { if (answers.isEmpty()) { /* ... */ } else { /* ... */ } } }
  • 42. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { // Fast and no side-effects Column { if (answers.isEmpty()) { /* ... */ } else { /* ... */ } } }
  • 43. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { Column { answers.forEach { answer -> SurveyAnswer(answer = answer) } } }
  • 44. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = false, ) } }
  • 45. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = false, ) } }
  • 46. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = false, ) } }
  • 47. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { var selectedAnswer: Answer? = null answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = false, ) } }
  • 48. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { var selectedAnswer: Answer? = null answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = false, ) } }
  • 49. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { var selectedAnswer: MutableState<Answer?> = mutableStateOf(null) answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = false, ) } }
  • 50. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { var selectedAnswer: MutableState<Answer?> = mutableStateOf(null) answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = false, ) } }
  • 51. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { var selectedAnswer: MutableState<Answer?> = mutableStateOf(null) answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = (selectedAnswer.state == answer), ) } }
  • 52. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { var selectedAnswer: MutableState<Answer?> = remember { mutableStateOf(null) } answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = (selectedAnswer.state == answer), ) } }
  • 53. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { var selectedAnswer: MutableState<Answer?> = rememberSaveable { mutableStateOf(null) } answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = (selectedAnswer.state == answer), ) } }
  • 54. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { var selectedAnswer: Answer? by rememberSaveable { mutableStateOf(null) } answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = (selectedAnswer.state == answer), ) } }
  • 55. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { var selectedAnswer: Answer? by rememberSaveable { mutableStateOf(null) } answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = (selectedAnswer == answer), ) } }
  • 56. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { var selectedAnswer: Answer? by rememberSaveable { mutableStateOf(null) } answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = (selectedAnswer == answer), onAnswerSelected = { answer -> selectedAnswer = answer } ) } }
  • 57. This work is licensed under the Apache 2.0 License Event handler UI element event state Events change State
  • 58. This work is licensed under the Apache 2.0 License Event handler UI element onAnswerSelected answer Events change State
  • 59. This work is licensed under the Apache 2.0 License // SingleChoiceQuestion.kt @Composable fun SingleChoiceQuestion(answers: List<Answer>) { val selectedAnswer: Answer? by rememberSaveable { mutableStateOf<Answer>(null) } answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = (selectedAnswer == answer), onAnswerSelected = { answer -> selectedAnswer = answer } ) } }
  • 60. This work is licensed under the Apache 2.0 License Composable functions can execute in any order.
  • 61. This work is licensed under the Apache 2.0 License // ButtonRow.kt @Composable fun ButtonRow() { MyFancyNavigation { StartScreen() MiddleScreen() EndScreen() } }
  • 62. This work is licensed under the Apache 2.0 License Composable functions can run in parallel.
  • 63. This work is licensed under the Apache 2.0 License @Composable fun ListComposable(myList: List<String>) { Row(horizontalArrangement = Arrangement.SpaceBetween) { Column { for (item in myList) { Text("Item: $item") } } Text("Count: ${myList.size}") } } // ListComposable.kt
  • 64. This work is licensed under the Apache 2.0 License @Composable fun ListWithBug(myList: List<String>) { var items = 0 Row(horizontalArrangement = Arrangement.SpaceBetween) { Column { for (item in myList) { Text("Item: $item”) items++ // Avoid! Side-effect of the column recomposing. } } Text("Count: $items") } } // ListComposable.kt
  • 65. This work is licensed under the Apache 2.0 License Recomposition skips as much as possible.
  • 66. This work is licensed under the Apache 2.0 License @Composable fun GreetingScreen(name: String) { Column { Header() Greeting(name = name) Footer() } } // GreenScreen.kt
  • 67. This work is licensed under the Apache 2.0 License Recomposition is optimistic.
  • 68. This work is licensed under the Apache 2.0 License Composable functions might run frequently.
  • 69. This work is licensed under the Apache 2.0 License Summary Create composables using the @Composable annotation It’s quick & easy to create composables Composables accept parameters Use MutableState and remember Composables should be side-effect free
  • 70. This work is licensed under the Apache 2.0 License Composables can: Execute in any order Run in parallel Be skipped Run frequently 1 2 3 4
  • 71. This work is licensed under the Apache 2.0 License Compose Toolkit
  • 72. This work is licensed under the Apache 2.0 License goo.gle/compose-samples
  • 73. This work is licensed under the Apache 2.0 License
  • 74. This work is licensed under the Apache 2.0 License
  • 75. This work is licensed under the Apache 2.0 License MaterialTheme( colorScheme = MyAppsColorScheme, typography = MyAppsTypography, shapes = MyAppsShapes ) { // Content goes here }
  • 76. This work is licensed under the Apache 2.0 License
  • 77. This work is licensed under the Apache 2.0 License
  • 78. This work is licensed under the Apache 2.0 License
  • 79. This work is licensed under the Apache 2.0 License
  • 80. This work is licensed under the Apache 2.0 License
  • 81. This work is licensed under the Apache 2.0 License Scaffold( topBar = { SmallTopAppBar(/* ... */) }, floatingActionButtonPosition = FabPosition.End, floatingActionButton = { FloatingActionButton(/* ... */) }, content = { /* ... */ } )
  • 82. This work is licensed under the Apache 2.0 License SurveyTopAppBar SurveyBottomBar Question
  • 83. This work is licensed under the Apache 2.0 License
  • 84. This work is licensed under the Apache 2.0 License
  • 85. This work is licensed under the Apache 2.0 License
  • 86. This work is licensed under the Apache 2.0 License
  • 87. This work is licensed under the Apache 2.0 License
  • 88. This work is licensed under the Apache 2.0 License Surface { Text("Hello Compose") } Hello Compose
  • 89. This work is licensed under the Apache 2.0 License Surface( color = MaterialTheme.colorScheme.primary, ) { Text("Hello Compose") } Hello Compose
  • 90. This work is licensed under the Apache 2.0 License Surface( color = MaterialTheme.colorScheme.primary, shape = RoundedCornerShape(8.dp), ) { Text("Hello Compose") } Hello Compose
  • 91. This work is licensed under the Apache 2.0 License Surface( color = MaterialTheme.colorScheme.surface, shape = RoundedCornerShape(8.dp), border = BorderStroke(2.dp, MaterialTheme.colorScheme.outline ) ) { Text("Hello Compose") } Hello Compose
  • 92. This work is licensed under the Apache 2.0 License Surface( color = MaterialTheme.colorScheme.surface, shape = RoundedCornerShape(8.dp), border = BorderStroke(2.dp, MaterialTheme.colorScheme.surfaceVariant ), shadowElevation = 8.dp, tonalElevation = 8.dp, ) { Text("Hello Compose") } Hello Compose
  • 93. This work is licensed under the Apache 2.0 License
  • 94. This work is licensed under the Apache 2.0 License
  • 96. This work is licensed under the Apache 2.0 License Standard layouts
  • 97. This work is licensed under the Apache 2.0 License Row { Component1() Component2() Component3() } 1 2 3 Row
  • 98. This work is licensed under the Apache 2.0 License 1 2 3 Column Column { Component1() Component2() Component3() }
  • 99. This work is licensed under the Apache 2.0 License 2 1 3 Box Box { Component1() Component2() Component3() }
  • 100. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Row { Image(answer.image) Text(answer.text) RadioButton(/* … */) } }
  • 101. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Row( verticalAlignment = Alignment.CenterVertically ) { /* ... */ } }
  • 102. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { /* ... */ } }
  • 104. This work is licensed under the Apache 2.0 License Modifiers
  • 105. This work is licensed under the Apache 2.0 License Text("Hello Compose") Hello Compose
  • 106. This work is licensed under the Apache 2.0 License Text( "Hello Compose!", Modifier.background(Color.Magenta) ) Hello Compose
  • 107. This work is licensed under the Apache 2.0 License Text( "Hello Compose!", Modifier.background(Color.Magenta) .size(200.dp, 30.dp) ) Hello Compose
  • 108. This work is licensed under the Apache 2.0 License Text( "Hello Compose!", Modifier.background(Color.Magenta) .size(200.dp, 30.dp) .padding(5.dp) ) Hello Compose
  • 109. This work is licensed under the Apache 2.0 License Text( "Hello Compose!", Modifier.background(Color.Magenta) .size(200.dp, 30.dp) .padding(5.dp) .alpha(0.5f) ) Hello Compose
  • 110. This work is licensed under the Apache 2.0 License Text( "Hello Compose!", Modifier.background(Color.Magenta) .size(200.dp, 30.dp) .padding(5.dp) .alpha(0.5f) .clickable { // Called when Text clicked } ) Hello Compose
  • 111. This work is licensed under the Apache 2.0 License Box(Modifier.size(150.dp)) { Text("Hello Compose") } Hello Compose
  • 112. This work is licensed under the Apache 2.0 License Box(Modifier.size(150.dp)) { Text( "Hello Compose!", Modifier.align( Alignment.BottomEnd ) ) } Hello Compose
  • 113. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Row(...) { Image(answer.image) Text(answer.text) RadioButton(/* … */) } } Desired Current
  • 114. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Row( Modifier.fillMaxWidth(), /* ... */ ) { Image(answer.image) Text(answer.text) RadioButton(/* ... */) } } Desired Current
  • 115. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Row( Modifier.fillMaxWidth() .padding(16.dp), /* ... */ ) { Image(answer.image) Text(answer.text) RadioButton(/* ... */) } } Desired Current
  • 116. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Surface( border = BorderStroke( 1.dp, MaterialTheme.colorScheme.outline ), shape = MaterialTheme.shapes.small ) { Row(/* ... */) { } } } Desired Current
  • 118. This work is licensed under the Apache 2.0 License @Composable fun SurveyAnswer(answer: Answer) { Surface( border = BorderStroke( 1.dp, MaterialTheme.colorScheme.outline ), shape = MaterialTheme.shapes.small ) { Row(Modifier.fillMaxWidth().padding(16.dp)) { Image(answer.image) Text(answer.text) RadioButton(/* … */) } } }
  • 119. This work is licensed under the Apache 2.0 License Compose Tooling
  • 120. This work is licensed under the Apache 2.0 License Live demo!