Introduction
Jetpack Compose is a modern UI toolkit for building native Android applications. One of its most exciting features is the ability to create and manage UI components declaratively, which makes designing UIs faster and more intuitive. In this article, we'll explore how to implement bottom navigation using Jetpack Compose in Android Kotlin, focusing on a simple example that demonstrates the interaction between a scaffold, bottom navigation, and floating action buttons.
Bottom navigation is a key component in mobile applications, providing easy access to core functionality in a user-friendly manner. Using Jetpack Compose, we can achieve a highly customizable and responsive bottom navigation layout, which can significantly enhance the overall user experience.
Breakdown of the Code: 1. Main Activity Setup
The entry point of the app is the MainActivity
, which extends AppCompatActivity
. Within the onCreate
function, the content of the activity is set using setContent
, a Jetpack Compose-specific method that takes a composable function as its parameter. In this case, the composable function GetScaffold
is invoked, which sets up the primary structure of the UI, including a top app bar, main content, a bottom navigation bar, and a floating action button.
This method simplifies the process of creating the UI, as it eliminates the need for XML layouts and traditional view hierarchies.
2. The Scaffold Structure
At the core of this example is the Scaffold composable, which acts as a layout container for the top bar, bottom navigation, main content, and a floating action button. The scaffold provides a structure where different sections of the UI can be neatly arranged. In this example, it consists of a TopAppBar for displaying a title, a FloatingActionButton, and a BottomAppBar for navigation.
The TopAppBar
sets a static title for the app, while the BottomAppBar
contains navigation items that allow users to switch between different states.
3. Bottom Navigation
The BottomBarContent
composable function is responsible for creating the bottom navigation bar. Inside this function, the BottomAppBar
houses three BottomNavigationItem components, each representing a different action: "Add," "ThumbUp," and "Delete."
Each navigation item is visually represented by an icon and text label, and the current selection is tracked using selectedItem
, which is a MutableState
variable. When an item is clicked, it updates the selectedItem
value, which is then displayed in the main content area.
4. Floating Action Button
The FloatingActionButton (FAB) adds another layer of interaction to the UI. In this example, the FAB is styled with a custom shape (CutCornerShape
), which gives it a distinctive angular design. The icon inside the FAB is a heart (favorite) symbol, making it a prominent element of the screen.
The FAB is docked into the BottomAppBar
using the isFloatingActionButtonDocked
parameter, ensuring that it stays aligned with the navigation bar, enhancing the layout's visual appeal.
5. Main Content
The MainContent
composable function dynamically displays the current selection made through the bottom navigation. It uses a simple Box
layout, which centers the text on the screen, making it responsive to screen size changes.
The text updates in real-time based on the selected item from the bottom navigation, demonstrating how Compose's reactive system efficiently updates the UI when state changes.
Summary
This example illustrates the power and simplicity of Jetpack Compose when building an Android application with a bottom navigation layout. By using composables like Scaffold
, BottomAppBar
, and FloatingActionButton
, we can create a clean, responsive interface with minimal code.
Jetpack Compose’s declarative approach allows for seamless UI updates and easy management of state, making it an excellent choice for building modern Android UIs. As demonstrated, the code is easy to read and maintain, providing developers with flexibility and control over their app's design and behavior.
package com.cfsuman.jetpackcompose
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CutCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.Color
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AddCircle
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.ThumbUp
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
GetScaffold()
}
}
@Composable
fun GetScaffold(){
val selectedItem = remember { mutableStateOf("Add")}
Scaffold(
topBar = {
TopAppBar(
title = { Text(
text = "Compose - Bottom Navigation"
)},
backgroundColor = Color(0xFFC0E8D5),
)
},
content = {MainContent(selectedItem)},
backgroundColor = Color(0xFFEDEAE0),
bottomBar = { BottomBarContent(selectedItem) },
floatingActionButton = {
FloatingActionButton(
onClick = {
// do something here
},
shape = CutCornerShape(45.dp)
) {
Icon(Icons.Filled.Favorite, contentDescription = "")
}
},
isFloatingActionButtonDocked = true
)
}
@Composable
fun BottomBarContent(selectedItem: MutableState<String>){
BottomAppBar(
elevation = 4.dp,
cutoutShape = CutCornerShape(45.dp)
) {
BottomNavigation() {
BottomNavigationItem(
icon = {Icon(Icons.Filled.AddCircle,"")},
selected = selectedItem.value == "Add",
onClick = { selectedItem.value = "Add" },
label = {Text(text = "Add")},
alwaysShowLabel = false
)
BottomNavigationItem(
icon = {Icon(Icons.Filled.ThumbUp,"")},
selected = selectedItem.value == "ThumbUp",
onClick = { selectedItem.value = "ThumbUp" },
label = {Text(text = "ThumbUp")},
alwaysShowLabel = false
)
BottomNavigationItem(
icon = {Icon(Icons.Filled.Delete,"")},
selected = selectedItem.value == "Delete",
onClick = { selectedItem.value = "Delete" },
label = {Text(text = "Delete")},
alwaysShowLabel = false
)
}
}
}
@Composable
fun MainContent(selectedItem: MutableState<String>){
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
){
Text(
text = "Selected ${selectedItem.value}",
fontWeight = FontWeight.Bold
)
}
}
}
- jetpack compose - How to use AndroidView
- jetpack compose - How to update AndroidView
- jetpack compose - AndroidView click event
- jetpack compose - AndroidView modifier
- jetpack compose - String resource plurals
- jetpack compose - Accessing font resource
- jetpack compose - LazyColumn smooth scrolling
- jetpack compose - SlideIn SlideOut animation
- jetpack compose - Tween animation
- jetpack compose - AnimateContentSize customization
- jetpack compose - AnimateDpAsState
- jetpack compose - Make Text clickable
- jetpack compose - Draw rounded rectangle on canvas
- jetpack compose - Draw arc on canvas
- jetpack compose - Long press listener