Leave a rating/review
Notes: 03. Use Basic Compose Building Blocks
The student materials have been reviewed and are updated as of September 2022.
In ui/addBook/AddBookActivity, within AddBookTopBar() composable function, the method onBackPressed() is deprecated and is replaced by onBackPressedDispatcher.onBackPressed() method.
Demo
Now that you’ve learned a bit about basic composable functions and how they work, you’re ready to dive deeper and learn about more composables and how to combine them together.
Let’s do that, by opening the AddBookActivity. Add the starting code, to set up the basic UI:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent { AddBookContent() } // here
}
@Composable
fun AddBookContent() {
Scaffold(topBar = { AddBookTopBar() }) {
AddBookFormContent()
}
}
Nothing special here, just adding the basic content like before. Now add the TopBar composable like so:
Note
@Composable
fun AddBookTopBar() {
TopAppBar(
title = {
Text(text = stringResource(id = R.string.add_book_title))
},
navigationIcon = {
IconButton(onClick = { onBackPressedDispatcher.onBackPressed() }) {
Icon(Icons.Default.ArrowBack, contentDescription = "Back")
}
},
contentColor = Color.White,
backgroundColor = colorResource(id = R.color.colorPrimary)
)
}
This is a more complex definition than the previous ones. You added the navigationIcon to represent the back button, and within it you built the IconButton. Now your TopBar will have a back arrow that lets you return to the BooksFragment.
Now add the form content composable function:
@Composable
fun AddBookFormContent() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
}
}
This is another new component in Compose. A Column is basically a LinearLayout, where the orientation is vertical. There’s another component called Row, which is a horizontal LinearLayout. You put the horizontal alignment here to be Alignment.CenterHorizontally, to make the items appear centered. You also used the Modifier.fillMaxSize() parameter.
[Slide 1 - Modifiers]
Modifiers are used to edit or modify your UI components. There’s lots of modifiers, for gravity, size, padding, borders, backgrounds and much more.
They can be stacked, meaning you can just chain calls, and add lots of different styling to your apps! :]
You’ll learn about different types of modifiers throughout the course, but you can feel free to check them out yourself!
[Switch to demo]
Now add the following two elements to the Column, to represent your input fields:
@Composable
fun AddBookFormContent() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
OutlinedTextField(
value = "",
onValueChange = {},
label = { Text(text = stringResource(id = R.string.book_title_hint)) })
OutlinedTextField(
value = "",
onValueChange = {},
label = { Text(text = stringResource(id = R.string.book_description_hint)) })
}
}
The OutlinedTextField is a material-based component that lets the user write some text, just like an EditText.
You added the value of the text, and the label to the fields, and an onValueChange callback. The label is another composable, representing the state of the component when there’s no input or focus, similar to what a hint does. And the onValueChange callback is just like a text changed listener, giving you new values.
Because you’re using a Column, the items will be positioned one underneath the other.
Now add the following component to the Column to represent the drop down menu, or a spinner, for Genres:
@Composable
fun AddBookFormContent() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
...
Row {
TextButton(
onClick = {},
content = { Text(text = stringResource(id = R.string.genre_select)) })
DropdownMenu(
expanded = false,
onDismissRequest = {}) {
DropdownMenuItem(onClick = {}) {
}
}
}
}
}
Quite a bit of code here too! You used a Row to show items in a horizontal order. Then you added the DropdownMenu.
The DropdownMenu has a content component that holds the menu items. It also needs to know if it’s expanded or not, how to react to dismiss requests. You also added a TextButton that you’ll use to toggle if the menu is expanded.
You haven’t filled in the menu content with genres yet, you’ll do that in the next episode. But each menu item can have any UI you need, and has a click listener that lets you react to item selection.
You’ll see how to handle that in the next episode! :]
For now, add the following button to complete the form UI:
@Composable
fun AddBookFormContent() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
...
TextButton(
onClick = { onAddBookTapped() }
) {
Text(text = stringResource(id = R.string.add_book_button_text))
}
}
}
The TextButton is similar to a regular button, except that it doesn’t have a regular background. You’ll be editing all the UI a bit later, to make it extra nice, but for now, this button works! :]
Now build & run the app to check out your UI.
[Build & run]
The UI looks nice and seems to be there, but there are some obvious parts missing. The Input fields don’t change their value as you type them, and the genre picker doesn’t have any items to pick from!
This is because Compose doesn’t handle state on its own, you have to define declaratively how the state behaves and how to represent it on the screen. You’ll add all this in the next episode! :]