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