Jetpack Compose Grocery App UI | Dashboard App Part 3
In this article, I make a jetpack compose grocery app UI. Also, you can learn from previse articles part 1and part 2 here I create a UI for the jetpack compose App bar and Jetpack Compose a horizontal list to show the Banner and category or product.
In this blog, I complete the screen full Ui And add the bestseller list at the bottom of the screen. Jetpack compose is the newest tool for Making UI in native android apps without XML. Let’s Follow the below code for making a grocery app UI in android.
Start your android studio and create a new project if you do not have any existing projects. If You have an exciting open it and also you can read Dashboard App Part 1 and Part 2 to understand more n these.
So In this Project, I Use an AppBar and Add a menu in the ToAppBar then I create a header Ui and add payment here. After the header, I add a promotion Banner UI and the I Show a Category of product list this UI example I also share in Part1 and part2 in this I add a best seller product list.
Jetpack Compose Grocery App UI | Dashboard App Part 3
- TopAppBar With Search view and Notification.
- Header Section with Payout options
- Promotional Banner List
- Category
- Best Sellers
Step:- Full Souce Code MainActivity.kt
package com.codeplayon.jetpackdashboard import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.FavoriteBorder import androidx.compose.material.icons.outlined.Notifications import androidx.compose.material.icons.rounded.Search import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.codeplayon.jetpackdashboard.ui.theme.JetpackDashboardTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MainTheme { HomeScreen() } } } } @Composable fun MainTheme(content: @Composable () -> Unit) { JetpackDashboardTheme { Surface(color = MaterialTheme.colors.background) { content() } } } @Preview(showBackground = true) @Composable fun DefaultPreview() { MainTheme { HomeScreen() } } @Composable fun HomeScreen() { Box(Modifier.verticalScroll(rememberScrollState())) { Image( modifier = Modifier .fillMaxWidth() .offset(0.dp, (-30).dp), painter = painterResource(id = R.drawable.bg_main), contentDescription = "Header Background", contentScale = ContentScale.FillWidth ) Column { AppBar() Content() } } } @Composable fun AppBar() { Row( Modifier .padding(16.dp) .height(48.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceAround ) { var text by remember { mutableStateOf("Search....") } TextField( value = text, onValueChange = {text = it}, // label = { Text(text = "Search....", fontSize = 12.sp) }, singleLine = true, leadingIcon = { Icon(imageVector = Icons.Rounded.Search, contentDescription = "Search") }, colors = TextFieldDefaults.textFieldColors( backgroundColor = Color.White, focusedIndicatorColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent ), shape = RoundedCornerShape(8.dp), modifier = Modifier .weight(1f) .fillMaxHeight() ) Spacer(modifier = Modifier.width(8.dp)) IconButton(onClick = { }) { Icon(imageVector = Icons.Outlined.FavoriteBorder, contentDescription = "", tint = Color.White) } IconButton(onClick = {}) { Icon(imageVector = Icons.Outlined.Notifications, contentDescription = "", tint = Color.White) } } } @Composable fun Content() { Column() { Header() Spacer(modifier = Modifier.height(16.dp)) Promotions() Spacer(modifier = Modifier.height(16.dp)) CategorySection() Spacer(modifier = Modifier.height(16.dp)) BestSellerSection() Spacer(modifier = Modifier.height(16.dp)) } } @Composable fun Header() { Card( Modifier .height(64.dp) .padding(horizontal = 16.dp), elevation = 4.dp, shape = RoundedCornerShape(8.dp) ) { Row( Modifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically ) { QrButton() VerticalDivider() Row(Modifier .fillMaxHeight() .weight(1f) .clickable { } .padding(horizontal = 8.dp), verticalAlignment = Alignment.CenterVertically ) { Icon(painter = painterResource(id = R.drawable.ic_money), contentDescription = "", tint = Color(0xFF6FCF97)) Column(Modifier.padding(8.dp)) { Text(text = "$250", fontWeight = FontWeight.Bold, fontSize = 16.sp) Text(text = "Top Up", color = MaterialTheme.colors.primary, fontSize = 12.sp) } } VerticalDivider() Row(Modifier .fillMaxHeight() .weight(1f) .clickable { } .padding(horizontal = 8.dp), verticalAlignment = Alignment.CenterVertically ) { Icon(painter = painterResource(id = R.drawable.ic_coin), contentDescription = "", tint = MaterialTheme.colors.primary) Column(Modifier.padding(8.dp)) { Text(text = "$50", fontWeight = FontWeight.Bold, fontSize = 16.sp) Text(text = "Points", color = Color.LightGray, fontSize = 12.sp) } } } } } @Composable fun QrButton() { IconButton( onClick = {}, modifier = Modifier .fillMaxHeight() .aspectRatio(1f) ) { Icon( painter = painterResource(id = R.drawable.ic_scan), contentDescription = "", modifier = Modifier .fillMaxSize() .padding(16.dp) ) } } @Composable fun VerticalDivider() { Divider( color = Color(0xFFF1F1F1), modifier = Modifier .width(1.dp) .height(32.dp) ) } @Composable fun Promotions() { LazyRow( Modifier.height(160.dp), contentPadding = PaddingValues(horizontal = 16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp) ) { item { PromotionItem( imagePainter = painterResource(id = R.drawable.promotion), title = "Fruit", subtitle = "Start @", header = "$2", backgroundColor = MaterialTheme.colors.primary ) } item { PromotionItem( imagePainter = painterResource(id = R.drawable.promotion), title = "Vegetables", subtitle = "Discount", header = "35%", backgroundColor = Color(0xffF2994A) ) } } } @Composable fun PromotionItem( title: String = "", subtitle: String = "", header: String = "", backgroundColor: Color = Color.Transparent, imagePainter: Painter ) { Card( Modifier.width(300.dp), shape = RoundedCornerShape(8.dp), backgroundColor = backgroundColor, elevation = 0.dp ) { Row { Column( Modifier .padding(horizontal = 16.dp) .fillMaxHeight(), verticalArrangement = Arrangement.Center ) { Text(text = title, fontSize = 14.sp, color = Color.White) Text(text = subtitle, fontSize = 16.sp, color = Color.White, fontWeight = FontWeight.Bold) Text(text = header, fontSize = 28.sp, color = Color.White, fontWeight = FontWeight.Bold) } Image( painter = imagePainter, contentDescription = "", modifier = Modifier .fillMaxHeight() .weight(1f), alignment = Alignment.CenterEnd, contentScale = ContentScale.Crop ) } } } @Composable fun CategorySection() { Column(Modifier.padding(horizontal = 16.dp)) { Row( Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { Text(text = "Category", style = MaterialTheme.typography.h6) TextButton(onClick = {}) { Text(text = "More", color = MaterialTheme.colors.primary) } } Row( Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { CategoryButton( text = "Dairy", icon = painterResource(id = R.drawable.ic_cheese), backgroundColor = Color(0xffFFFBF3) ) CategoryButton( text = "Vegetables", icon = painterResource(id = R.drawable.ic_veg), backgroundColor = Color(0xffF6FBF3) ) CategoryButton( text = "Fruits", icon = painterResource(id = R.drawable.ic_orange), backgroundColor = Color(0xffFEF4E7) ) CategoryButton( text = "Meats", icon = painterResource(id = R.drawable.ic_meat), backgroundColor = Color(0xffF6E6E9) ) } } } @Composable fun CategoryButton( text: String = "", icon: Painter, backgroundColor: Color ) { Column( Modifier .width(72.dp) .clickable { } ) { Box( Modifier .size(72.dp) .background( color = backgroundColor, shape = RoundedCornerShape(12.dp) ) .padding(18.dp) ) { Image(painter = icon, contentDescription = "", modifier = Modifier.fillMaxSize()) } Text(text = text, modifier = Modifier.fillMaxWidth(), textAlign = TextAlign.Center, fontSize = 12.sp) } } @Composable fun BestSellerSection() { Column() { Row( Modifier .fillMaxWidth() .padding(horizontal = 16.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { Text(text = "Best Sellers", style = MaterialTheme.typography.h6) TextButton(onClick = {}) { Text(text = "More", color = MaterialTheme.colors.primary) } } BestSellerItems() } } @Composable fun BestSellerItems() { LazyRow( contentPadding = PaddingValues(horizontal = 16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp) ) { item { BestSellerItem( imagePainter = painterResource(id = R.drawable.item_lettuce), title = "Iceberg Lettuce", price = "3.41", backgroundColor = Color(0xffF6FBF3), discountPercent = 10 ) } item { BestSellerItem( imagePainter = painterResource(id = R.drawable.item_apple), title = "Apple", price = "1.43", backgroundColor = Color(0xffFEF4E7), discountPercent = 5 ) } item { BestSellerItem( imagePainter = painterResource(id = R.drawable.item_meat), title = "Meat", price = "4.31", backgroundColor = Color(0xffF6E6E9), discountPercent = 20 ) } } } @Composable fun BestSellerItem( title: String = "", price: String = "", discountPercent: Int = 0, imagePainter: Painter, backgroundColor: Color ) { Card( Modifier .width(130.dp) ) { Column( Modifier .background( color = backgroundColor, shape = RoundedCornerShape(0.dp) ) .padding(bottom = 20.dp) ) { Image( painter = imagePainter, contentDescription = "", modifier = Modifier .fillMaxWidth() .aspectRatio(1f), contentScale = ContentScale.Fit ) Column( Modifier .fillMaxWidth() .padding(horizontal = 8.dp) ) { Text(text = title, fontWeight = FontWeight.Bold) Row { Text( "$${price}", textDecoration = if (discountPercent > 0) TextDecoration.LineThrough else TextDecoration.None, color = if (discountPercent > 0) Color.Gray else Color.Black ) if (discountPercent > 0) { Text(text = "[$discountPercent%]", color = MaterialTheme.colors.primary) } } } } } }
You can use this final code to make a Grocery App UI using Jetpack Compose. here is some of the image drawable file in missing you can see an error on this file you can set your icon here if you want the full file and source you can get it on Codeplayon GitHub account.
Read More Tutorial