-
-
Notifications
You must be signed in to change notification settings - Fork 371
/
Copy pathViewLayoutConfigurationsActivity.kt
459 lines (424 loc) · 20.2 KB
/
ViewLayoutConfigurationsActivity.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
package com.example.jetpackcompose.layout
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.FirstBaseline
import androidx.activity.compose.setContent
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.sp
import com.example.jetpackcompose.image.TitleComponent
class ViewLayoutConfigurationsActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// This is an extension function of Activity that sets the @Composable function that's
// passed to it as the root view of the activity. This is meant to replace the .xml file
// that we would typically set using the setContent(R.id.xml_file) method. The setContent
// block defines the activity's layout.
setContent {
// LazyColumn is a vertically scrolling list that only composes and lays out the currently
// visible items. This is very similar to what RecyclerView tries to do as well.
LazyColumn {
// item is a DSL available in the LazyColumn scope. This allows you to render a composable
// for a single element in the list
item {
// Title Component is a custom composable that we created which is capable of
// rendering text on the screen in a certain font style & text size.
TitleComponent("Child views with equal weights")
RowEqualWeightComponent()
}
item {
TitleComponent("Child views with unequal weights")
RowUnequalWeightComponent()
}
item {
TitleComponent("Child view with auto space in between")
RowAddSpaceBetweenViewsComponent()
}
item {
TitleComponent("Child views spaced evenly")
RowSpaceViewsEvenlyComponent()
}
item {
TitleComponent("Space added around child views")
RowSpaceAroundViewsComponent()
}
item {
TitleComponent("Child views centered")
RowViewsCenteredComponent()
}
item {
TitleComponent("Child views arranged in end")
RowViewsArrangedInEndComponent()
}
item {
TitleComponent("Baseline of child views aligned")
RowBaselineAlignComponent()
}
item {
TitleComponent("Baseline of child views not aligned")
RowBaselineUnalignedComponent()
}
}
}
}
}
// We represent a Composable function by annotating it with the @Composable annotation. Composable
// functions can only be called from within the scope of other composable functions. We should
// think of composable functions to be similar to lego blocks - each composable function is in turn
// built up of smaller composable functions.
@Composable
fun RowEqualWeightComponent() {
// Row is a composable that places its children in a horizontal sequence. You can think of it
// similar to a LinearLayout with the horizontal orientation. In addition, we pass a modifier
// to the Row composable. You can think of Modifiers as implementations of the decorators
// pattern that are used to modify the composable that its applied to. In this example, we
// assign add a modifier to the Row and ask it to extend the full width available to it.
// Alternatively, we could've assigned a fixed width to this row using
// Modifier.width(val width: Dp).
Row(modifier = Modifier.fillMaxWidth()) {
// Button is a pre-defined Material Design implementation of a contained button -
// https://material.io/design/components/buttons.html#contained-button.
// This Row consists of two buttons. We wanted to ensure that both these buttons occupy
// equal amount of width. We do that by using the Modifier.weight modifier and passing equal
// weight to both the buttons. This is similar to how we used layout_weight with
// LinearLayouts in the old Android UI Toolkit.
Button(modifier = Modifier
.weight(1f)
.padding(4.dp), onClick = {}) {
// The Button composable allows you to provide child composables that inherit this button
// functionality.
// The Text composable is pre-defined by the Compose UI library; you can use this
// composable to render text on the screen
Text(
text = "Button 1",
style = TextStyle(fontSize = 20.sp)
)
}
Button(modifier = Modifier
.weight(1f)
.padding(4.dp), onClick = {}) {
Text(
text = "Button 2",
style = TextStyle(fontSize = 20.sp)
)
}
}
}
@Composable
fun RowUnequalWeightComponent() {
// Row is a composable that places its children in a horizontal sequence. You can think of it
// similar to a LinearLayout with the horizontal orientation. In addition, we pass a modifier
// to the Row composable. You can think of Modifiers as implementations of the decorators
// pattern that are used to modify the composable that its applied to. In this example, we
// assign add a modifier to the Row and ask it to extend the full width available to it.
// Alternatively, we could've assigned a fixed width to this row using
// Modifier.width(val width: Dp).
Row(modifier = Modifier.fillMaxWidth()) {
// Button is a pre-defined Material Design implementation of a contained button -
// https://material.io/design/components/buttons.html#contained-button.
// This Row consists of two buttons. We wanted to ensure that both the first button
// occupies 2/3rd of the screen and the other button occupies the remaining 1/3rd.
// We do this by using the Modifier.weight modifier and passing equal weight to both the
// buttons. This is similar to how we used layout_weight with LinearLayouts in the old
// Android UI Toolkit.
Button(modifier = Modifier
.weight(0.66f)
.padding(4.dp), onClick = {}) {
// The Button composable allows you to provide child composables that inherit this button
// functionality.
// The Text composable is pre-defined by the Compose UI library; you can use this
// composable to render text on the screen
Text(
text = "Button 1",
style = TextStyle(fontSize = 20.sp)
)
}
Button(modifier = Modifier
.weight(0.34f)
.padding(4.dp), onClick = {}) {
Text(
text = "Button 2",
style = TextStyle(fontSize = 20.sp)
)
}
}
}
@Composable
fun RowAddSpaceBetweenViewsComponent() {
// Row is a composable that places its children in a horizontal sequence. You can think of it
// similar to a LinearLayout with the horizontal orientation. In addition, we pass a modifier
// to the Row composable. You can think of Modifiers as implementations of the decorators
// pattern that are used to modify the composable that its applied to. In this example, we
// assign add a modifier to the Row and ask it to extend the full width available to it.
// We use Arrangement.SpaceBetween to place the children of the row such that they are spaced
// evenly across the main axis, without free space before the first child or after the last child.
Row(
modifier = Modifier
.fillMaxWidth()
.padding(4.dp),
horizontalArrangement = Arrangement
.SpaceBetween
) {
// Button is a pre-defined Material Design implementation of a contained button -
// https://material.io/design/components/buttons.html#contained-button.
Button(onClick = {}) {
// The Button composable allows you to provide child composables that inherit this button
// functionality.
// The Text composable is pre-defined by the Compose UI library; you can use this
// composable to render text on the screen
Text(
text = "Button 1",
style = TextStyle(fontSize = 20.sp)
)
}
Button(onClick = {}) {
Text(
text = "Button 2",
style = TextStyle(fontSize = 20.sp)
)
}
}
}
@Composable
fun RowSpaceViewsEvenlyComponent() {
// Row is a composable that places its children in a horizontal sequence. You can think of it
// similar to a LinearLayout with the horizontal orientation. In addition, we pass a modifier
// to the Row composable. You can think of Modifiers as implementations of the decorators
// pattern that are used to modify the composable that its applied to. In this example, we
// assign add a modifier to the Row and ask it to extend the full width available to it.
// We use Arrangement.SpaceEvenly to place the children of the row such that they are
// spaced evenly across the main axis, including free space before the first child and after
// the last child.
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
// Button is a pre-defined Material Design implementation of a contained button -
// https://material.io/design/components/buttons.html#contained-button.
Button(onClick = {}) {
// The Button composable allows you to provide child composables that inherit this button
// functionality.
// The Text composable is pre-defined by the Compose UI library; you can use this
// composable to render text on the screen
Text(
text = "Button 1",
style = TextStyle(fontSize = 20.sp)
)
}
Button(onClick = {}) {
Text(
text = "Button 2",
style = TextStyle(fontSize = 20.sp)
)
}
}
}
@Composable
fun RowSpaceAroundViewsComponent() {
// Row is a composable that places its children in a horizontal sequence. You can think of it
// similar to a LinearLayout with the horizontal orientation. In addition, we pass a modifier
// to the Row composable. You can think of Modifiers as implementations of the decorators
// pattern that are used to modify the composable that its applied to. In this example, we
// assign add a modifier to the Row and ask it to extend the full width available to it.
// We use Arrangement.SpaceAround to place the children of the row such that they are spaced
// evenly across the main axis, including free space before the first child and after the
// last child, but half the amount of space existing otherwise between two consecutive children.
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceAround) {
// Button is a pre-defined Material Design implementation of a contained button -
// https://material.io/design/components/buttons.html#contained-button.
Button(onClick = {}) {
// The Button composable allows you to provide child composables that inherit this button
// functionality.
// The Text composable is pre-defined by the Compose UI library; you can use this
// composable to render text on the screen
Text(
text = "Button 1",
style = TextStyle(fontSize = 20.sp)
)
}
Button(onClick = {}) {
Text(
text = "Button 2",
style = TextStyle(fontSize = 20.sp)
)
}
}
}
@Composable
fun RowViewsCenteredComponent() {
// Row is a composable that places its children in a horizontal sequence. You can think of it
// similar to a LinearLayout with the horizontal orientation. In addition, we pass a modifier
// to the Row composable. You can think of Modifiers as implementations of the decorators
// pattern that are used to modify the composable that its applied to. In this example, we
// assign add a modifier to the Row and ask it to extend the full width available to it.
// We use Arrangement.Center to place the children of the row such that they are as close as
// possible to the middle of the main axis.
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
// Button is a pre-defined Material Design implementation of a contained button -
// https://material.io/design/components/buttons.html#contained-button.
Button(onClick = {}, modifier = Modifier.padding(4.dp)) {
// The Button composable allows you to provide child composables that inherit this button
// functionality.
// The Text composable is pre-defined by the Compose UI library; you can use this
// composable to render text on the screen
Text(
text = "Button 1",
style = TextStyle(fontSize = 20.sp)
)
}
Button(onClick = {}, modifier = Modifier.padding(4.dp)) {
Text(
text = "Button 2",
style = TextStyle(fontSize = 20.sp)
)
}
}
}
@Composable
fun RowViewsArrangedInEndComponent() {
// Row is a composable that places its children in a horizontal sequence. You can think of it
// similar to a LinearLayout with the horizontal orientation. In addition, we pass a modifier
// to the Row composable. You can think of Modifiers as implementations of the decorators
// pattern that are used to modify the composable that its applied to. In this example, we
// assign add a modifier to the Row and ask it to extend the full width available to it.
// We use Arrangement.End to place the children of the row such that they are as close as
// possible to the end of the main axis.
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
// Button is a pre-defined Material Design implementation of a contained button -
// https://material.io/design/components/buttons.html#contained-button.
Button(onClick = {}, modifier = Modifier.padding(4.dp)) {
// The Button composable allows you to provide child composables that inherit this button
// functionality.
// The Text composable is pre-defined by the Compose UI library; you can use this
// composable to render text on the screen
Text(
text = "Button 1",
style = TextStyle(fontSize = 20.sp)
)
}
Button(onClick = {}, modifier = Modifier.padding(4.dp)) {
Text(
text = "Button 2",
style = TextStyle(fontSize = 20.sp)
)
}
}
}
@Composable
fun RowBaselineAlignComponent() {
// Row is a composable that places its children in a horizontal sequence. You can think of it
// similar to a LinearLayout with the horizontal orientation. In addition, we pass a modifier
// to the Row composable. You can think of Modifiers as implementations of the decorators
// pattern that are used to modify the composable that its applied to. In this example, we
// assign add a modifier to the Row and ask it to extend the full width available to it.
// Alternatively, we could've assigned a fixed width to this row using
// Modifier.width(val width: Dp).
Row(modifier = Modifier.fillMaxWidth()) {
// The Text composable is pre-defined by the Compose UI library; you can use this
// composable to render text on the screen
// In order to align the baseline of both the text composables, we use the
// Modifier.alignBy(FirstBaseline) modifier. FirstBaseline here means that we
// align the baseline of the first line of the Text Composable.
Text(
text = "Text 1",
style = TextStyle(fontSize = 20.sp, fontStyle = FontStyle.Italic),
modifier = Modifier.alignBy(alignmentLine = FirstBaseline)
)
Text(
text = "Text 2",
style = TextStyle(
fontSize = 40.sp, fontStyle = FontStyle.Normal,
fontWeight = FontWeight.Bold
),
modifier = Modifier.alignBy(alignmentLine = FirstBaseline)
)
}
}
@Composable
fun RowBaselineUnalignedComponent() {
// Row is a composable that places its children in a horizontal sequence. You can think of it
// similar to a LinearLayout with the horizontal orientation. In addition, we pass a modifier
// to the Row composable. You can think of Modifiers as implementations of the decorators
// pattern that are used to modify the composable that its applied to. In this example, we
// assign add a modifier to the Row and ask it to extend the full width available to it.
// Alternatively, we could've assigned a fixed width to this row using
// Modifier.width(val width: Dp).
Row(modifier = Modifier.fillMaxWidth()) {
// The Text composable is pre-defined by the Compose UI library; you can use this
// composable to render text on the screen
Text(
text = "Text 1",
style = TextStyle(fontSize = 20.sp, fontStyle = FontStyle.Italic)
)
Text(
text = "Text 2",
style = TextStyle(
fontSize = 40.sp, fontStyle = FontStyle.Normal,
fontWeight = FontWeight.Bold
)
)
}
}
/**
* Android Studio lets you preview your composable functions within the IDE itself, instead of
* needing to download the app to an Android device or emulator. This is a fantastic feature as you
* can preview all your custom components(read composable functions) from the comforts of the IDE.
* The main restriction is, the composable function must not take any parameters. If your composable
* function requires a parameter, you can simply wrap your component inside another composable
* function that doesn't take any parameters and call your composable function with the appropriate
* params. Also, don't forget to annotate it with @Preview & @Composable annotations.
*/
@Preview("Child views with equal weights")
@Composable
fun RowEqualWeightComponentPreview() {
RowEqualWeightComponent()
}
@Preview("Child views with unequal weights")
@Composable
fun RowUnequalWeightComponentPreview() {
RowUnequalWeightComponent()
}
@Preview("Child view with auto space in between arrangement")
@Composable
fun RowAddSpaceBetweenViewsComponentPreview() {
RowAddSpaceBetweenViewsComponent()
}
@Preview("Child views spaced evenly arrangement")
@Composable
fun RowSpaceViewsEvenlyComponentPreview() {
RowSpaceViewsEvenlyComponent()
}
@Preview("Space added around child views arrangement")
@Composable
fun RowSpaceAroundViewsComponentPreview() {
RowSpaceAroundViewsComponent()
}
@Preview("Child views centered arrangement")
@Composable
fun RowViewsCenteredComponentPreview() {
RowViewsCenteredComponent()
}
@Preview("Child views arranged in end")
@Composable
fun RowViewsArrangedInEndComponentPreview() {
RowViewsArrangedInEndComponent()
}
@Preview("Baseline of child views aligned")
@Composable
fun RowBaselineAlignComponentPreview() {
RowBaselineAlignComponent()
}
@Preview("Baseline of child views not aligned")
@Composable
fun RowBaselineUnalignedComponentPreview() {
RowBaselineUnalignedComponent()
}