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

On National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsOn National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsMebane Rash
 
General Principles of Intellectual Property: Concepts of Intellectual Proper...
General Principles of Intellectual Property: Concepts of Intellectual  Proper...General Principles of Intellectual Property: Concepts of Intellectual  Proper...
General Principles of Intellectual Property: Concepts of Intellectual Proper...Poonam Aher Patil
 
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
 
Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)Jisc
 
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
 
Exploring_the_Narrative_Style_of_Amitav_Ghoshs_Gun_Island.pptx
Exploring_the_Narrative_Style_of_Amitav_Ghoshs_Gun_Island.pptxExploring_the_Narrative_Style_of_Amitav_Ghoshs_Gun_Island.pptx
Exploring_the_Narrative_Style_of_Amitav_Ghoshs_Gun_Island.pptxPooja Bhuva
 
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptxHMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptxEsquimalt MFRC
 
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...Nguyen Thanh Tu Collection
 
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
 
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
 
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
 
ICT role in 21st century education and it's challenges.
ICT role in 21st century education and it's challenges.ICT role in 21st century education and it's challenges.
ICT role in 21st century education and it's challenges.MaryamAhmad92
 
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
 
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
 
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
 
This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.christianmathematics
 
How to Add New Custom Addons Path in Odoo 17
How to Add New Custom Addons Path in Odoo 17How to Add New Custom Addons Path in Odoo 17
How to Add New Custom Addons Path in Odoo 17Celine George
 
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...Amil baba
 
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
 
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
 

Recently uploaded (20)

On National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsOn National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan Fellows
 
General Principles of Intellectual Property: Concepts of Intellectual Proper...
General Principles of Intellectual Property: Concepts of Intellectual  Proper...General Principles of Intellectual Property: Concepts of Intellectual  Proper...
General Principles of Intellectual Property: Concepts of Intellectual Proper...
 
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
 
Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)
 
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
 
Exploring_the_Narrative_Style_of_Amitav_Ghoshs_Gun_Island.pptx
Exploring_the_Narrative_Style_of_Amitav_Ghoshs_Gun_Island.pptxExploring_the_Narrative_Style_of_Amitav_Ghoshs_Gun_Island.pptx
Exploring_the_Narrative_Style_of_Amitav_Ghoshs_Gun_Island.pptx
 
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptxHMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
 
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
 
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
 
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
 
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
 
ICT role in 21st century education and it's challenges.
ICT role in 21st century education and it's challenges.ICT role in 21st century education and it's challenges.
ICT role in 21st century education and it's challenges.
 
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
 
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
 
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
 
This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.
 
How to Add New Custom Addons Path in Odoo 17
How to Add New Custom Addons Path in Odoo 17How to Add New Custom Addons Path in Odoo 17
How to Add New Custom Addons Path in Odoo 17
 
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
 
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
 
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...
 

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!