Material Design 3 and its features
The release of Material Design 3 (Material 3) came with lots of new features to help us build UIs for our apps. Here are some of the features of Material Design 3:
- Dynamic color: This is a color system that sets the color of our apps to the color of the user’s wallpaper. The System UI also adapts to this color. This enables users to have that personalized feel for their apps. Please note that dynamic color only works for Android 12 and above devices.
- More components: Material 3 has a new set of improved components that are available for use. Some components have new UIs and others have been added to the APIs.
- Simplified typography: Material 3 has a much more simplified naming and grouping for typography. We have the following types: display, headline, title, body, and label, with each supporting small, medium, and large sizes. This makes it easier for us to define styles all across our apps.
- Improved color scheme: The color scheme has undergone a lot of improvements with the addition of more color schemes to fine-grain color customization. It’s also way easier for us to support both dark and light color schemes in our apps. In addition to that, they created a new tool, Material Theme Builder (https://m3.material.io/theme-builder), which allows us to generate and export dark and light theme colors for our apps.
- Simplified shapes: Similar to typography, shapes have also been simplified to the following: Extra Small, Small, Medium, Large, and Extra Large. All these shapes come with default values, which we can always override to use our own.
The good news for us is that from Android Studio Hedgehog onward, we have project templates that come set up with Material 3, which makes things easier for us. Even the project we created in Chapter 2 comes with Material 3 set up already.
Material 3 APIs and their predecessors offer a wide range of components for us to use in our apps. In the next subsection, we will be looking at some of the common ones.
Material components
The Material library comes with prebuilt components that we can use to build common UI components. Let us look at some of the commonly used components and some of the updates they had in Material 3.
Top app bars
This is a component displayed at the top of the screen. It has a title and can also have some actions that are related to the screen the user is on. Some of the common actions are the settings icon normally at the top right of the screen. In Material 3, we have four types of top app bars: center-aligned, small, medium, and large, as shown in the following figures.
Figure 4.1 – Small top app bar
Figure 4.2 – Center-aligned top app bar
Figure 4.3 – Medium top app bar
Figure 4.4 – Large top app bar
As seen in Figures 4.1 to 4.4, all the top bars have the same width and only differ in height and positioning of the title text.
Let us look at the sample code for one of these top app bars:
@OptIn(ExperimentalMaterial3Api::class) @Composable fun PacktCenterAlignedTopBar() { CenterAlignedTopAppBar( title = { Text(text = "Packt Publishing") } ) }
Here, we have our custom composable and, inside it, we are using the CenterAlignedTopBar
composable from Material 3 and passing in Text
to the title
composable. The other three (LargeTopAppBar
, MediumTopAppBar
, and TopAppBar
) are similar; the only difference is the composable that you will use. Notice that we have the @OptIn
annotation as these components are still experimental.
Next, let us look at the FloatingActionButton
component.
FloatingActionButton
Most apps use the component to represent a call to action that is frequently used in the app. For example, create a new chat in a chat app. It is normally positioned at the bottom right of the screen or elsewhere, depending on your use case. This is how we create the component:
FloatingActionButton( onClick = { /*TODO*/ }, content = { Icon( imageVector = Icons.Default.Add , contentDescription = "New Chat" ) } )
We use the FloatingActionButton
component from the Material 3 library. We have the onclick
argument on the composable and, inside the content
lambda, we pass in an Icon
composable that has an add icon. The preview should be the following:
Figure 4.5 – FloatingActionButton
The FloatingActionButton
component has these sizes: large, normal, and small, and you can use whichever fits your purpose.
We have another type of FloatingActionButton
component known as ExtendedFloatingActionButton
, which looks like this:
Figure 4.6 – ExtendedFloatingActionButton
As seen in the preceding figure, an ExtendedFloatingActionButton
component allows us to add more items to our FAB. They are wider than the normal FloatActionButton
components. In this case, we have a Text
composable with the text New Chat in addition to the icon. You can use it with or without the icon. The implementation for this is as follows:
ExtendedFloatingActionButton( onClick = { /*TODO*/ }, content = { Icon( imageVector = Icons.Default.Add , contentDescription = "New Chat" ) Text( modifier = Modifier.padding(10.dp), text = "New Chat" ) } )
Here, we used the ExtendedFloatingActionButton
component and still passed in the same parameters as before. The only difference is that inside the content, we pass in a text since the content
lambda exposes RowScope
, which means children composables will be arranged in a row.
Next, let us look at the bottom app bar components.
Bottom app bars
The bottom app bar components display navigation items at the bottom of the screen. They are normally useful for apps that have three to five primary destinations.
Let us look at the code for a bottom app bar:
BottomAppBar( actions = { Icon(imageVector = Icons.Rounded.Home, contentDescription = "Home Screen") Icon(imageVector = Icons.Rounded.ShoppingCart, contentDescription = "Cart Screen") Icon(imageVector = Icons.Rounded.AccountCircle, contentDescription = "Account Screen") } )
We use the BottomAppBar
component and, inside the actions
lambda, we pass in three Icon
composables to represent the items we are supposed to show. This is how the preview of the composable will look:
Figure 4.7 – BottomAppBar
In Figure 4,7, we can see we have three icons arranged horizontally.
Additionally, in BottomAppBar
, we can also provision a FloatingActionButton
component. We are going to use the FloatingActionButton
component that we used early on. The updated component code is as follows:
BottomAppBar( actions = { Icon(imageVector = Icons.Rounded.Home, contentDescription = "Home Screen") Icon(imageVector = Icons.Rounded.ShoppingCart, contentDescription = "Cart Screen") Icon(imageVector = Icons.Rounded.AccountCircle, contentDescription = "Account Screen") }, floatingActionButton = { PacktFloatingActionButton() } )
In the preceding code, we have used the floatingActionButton
parameter and passed in PacktFloatingActionButton()
that we created earlier. The updated preview will be as follows:
Figure 4.8 – BottomAppBar with FloatingActionButton
As seen in the preceding figure, our BottomAppBar
now has a nice FloatingActionButton
to its right. The FAB is automatically positioned for you to the right.
We have looked at the different components in isolation, but what happens when we want to place them on one screen together? Next, we are going to look at Scaffold
, which is meant for this.
Scaffold
This is a layout provided by Material Design that helps place all components on your screen in their desired positions with ease.
Let us look at a sample of Scaffold
that has a top app bar, a floating action button, text center-aligned on the screen, and a bottom navigation bar:
Scaffold( topBar = { PacktSmallTopAppBar() }, bottomBar = { PacktBottomNavigationBar() }, floatingActionButton = { PacktFloatingActionButton() }, content = { paddingValues -> Column( modifier = Modifier .fillMaxSize() .padding(paddingValues) .background(Color.Gray.copy(alpha = 0.1f)), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Text( modifier = Modifier.padding(10.dp), text = "Mastering Kotlin for Android Development - Chapter 4", textAlign = TextAlign.Center ) } } )
A lot is happening here, so let us break it down:
- The
Scaffold
composable is used to create a layout that implements the Material Design guidelines. It is a container that contains the top bar, bottom bar, floating action button, and the content. - The
topBar
parameter is used to specify the top bar. In this case, we are using thePacktSmallTopAppBar
composable that we created earlier. - The
bottomBar
parameter is used to specify the bottom bar. In this case, we are using thePacktBottomNavigationBar
composable. - The
floatingActionButton
parameter is used to specify the floating action button. In this case, we are using thePacktFloatingActionButton
composable. - The
content
parameter is used to specify the content of the screen. In this case, we are using aColumn
composable that contains aText
composable. The text is centered in the column using theverticalArrangement
andhorizontalAlignment
parameters. Notice that insideColumn
, we are using thepaddingValues
parameter to add padding to the column. This is because theScaffold
composable passes thepadding
values to thecontent
parameter.
With our Scaffold
composable ready, let us see how its preview looks:
Figure 4.9 – Scaffold
In Figure 4.9, we can see that the Scaffold
composable has added the top bar, bottom bar, and the floating action button to the screen. The components are also placed in the correct positions as per the Material Design guidelines.
We have learned about a bunch of components so far; Material 3 still offers more components out of the box for us. We will be using some of these components in the upcoming chapters of this book. To view the full list of all the components, go to the Material 3 Components website (https://m3.material.io/components) to see them and their guidelines.
Now that we understand Material 3 and its features, let us look at how to add it to our apps.