In this tutorial, you’ll build a clean Car Wala - Car Shop App using Jetpack Compose. Users will browse a list of cars, filter by brand, view car details, and see images, price, and description. No backend or database—just pure static data.
CarWala - Car Shopping App
CarWala is an interactive car shopping app built using Jetpack Compose. It lets users explore a variety of cars from different brands, view detailed information, and manage their shopping cart. Key features include:
- Brand Filtering: Browse cars by brand in a clean, organized list.
- Detailed Car Info: Each car comes with detailed specifications, pricing, and images.
- Cart Functionality: Add cars to the cart, modify quantities, and view the total price.
- Sleek UI: Modern and minimal design with smooth transitions and animations.
Perfect for anyone looking to buy or learn more about cars in a simple yet feature-rich environment!
🛠 Tech Stack
- Kotlin
- Jetpack Compose
- Navigation Compose
- Material 3 Design
- Static data model
Dependency we need
implementation ("androidx.compose.material:material-icons-extended:1.7.8")
implementation ("androidx.navigation:navigation-compose:2.8.9")
implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7")
Main Activity
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
CarWalaTheme {
/*Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}*/
CarWalaApp()
}
}
}
}
Car Wala App
package com.codingbihar.carwala
import androidx.compose.runtime.Composable
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
@Composable
fun CarWalaApp() {
val navController = rememberNavController()
val cartViewModel: CartViewModel = viewModel()
NavHost(navController = navController, startDestination = "welcome") {
composable("welcome") { WelcomeScreen(navController) }
composable("carList") { CarListScreen(navController) }
composable("carDetail/{carName}") { backStackEntry ->
val carName = backStackEntry.arguments?.getString("carName") ?: ""
CarDetailScreen(carName, navController, cartViewModel)
}
composable("brand/{brandName}") { backStackEntry ->
val brandName = backStackEntry.arguments?.getString("brandName")
BrandCarsScreen(brand = brandName ?: "", cars = cars, navController)
}
composable("cart") { CartScreen(navController, cartViewModel) }
}
}
Welcome Screen
package com.codingbihar.carwala
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
@Composable
fun WelcomeScreen(navController: NavController) {
Box(
modifier = Modifier
.fillMaxSize()
.background(brush = Brush.verticalGradient(
colors = listOf(Color(0xFF00BCD4), Color(0xFF009688)) // blue gradient
)),
contentAlignment = Alignment.Center
) {
Column(
Modifier.fillMaxSize().systemBarsPadding(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = " 🚗", fontSize = 320.sp)
Text(
text = "Welcome to CarWala",
style = MaterialTheme.typography.headlineLarge.copy(color = Color.White),
fontWeight = FontWeight.Bold
)
Text(
text = "Your Dream Car is Just a Click Away!",
style = MaterialTheme.typography.bodyLarge.copy(color = Color.White)
)
Spacer(modifier = Modifier.height(38.dp))
Button(
onClick = { navController.navigate("carList") },
modifier = Modifier.padding(bottom = 22.dp),
colors = ButtonDefaults.buttonColors(containerColor = Color.White)
) {
Text(text = "Start Now", style = MaterialTheme.typography.titleLarge, color = Color(0xFF2193b0))
}
}
}
}
Car List Screen
package com.codingbihar.carwala
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
@Composable
fun CarListScreen(navController: NavController) {
val brands = cars.map { it.brand }.distinct()
Column (Modifier.fillMaxSize().systemBarsPadding()
){
Text(text = stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineLarge,
color = MaterialTheme.colorScheme.secondary,
fontWeight = FontWeight.ExtraBold
)
LazyRow(modifier = Modifier.padding(8.dp)) {
// Find the first car for this brand to get the image
items(brands) { brand ->
// Circular Image
val brandCar = cars.first { it.brand == brand }
Column (Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally){
Image(
painter = painterResource(id = brandCar.images.first() ),
contentDescription = brand,
modifier = Modifier
.size(80.dp)
.clip(CircleShape)
.clickable(onClick = {
navController.navigate("brand/${brand}")
}),
contentScale = ContentScale.Fit
)
Button(
onClick = { navController.navigate("brand/${brand}") },
modifier = Modifier.padding(end = 8.dp)
) {
Text(text = brand)
}
}
}
}
LazyColumn(modifier = Modifier.systemBarsPadding()) {
items(cars) { car ->
Card(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
.clickable {
navController.navigate("carDetail/${car.name}")
},
elevation = CardDefaults.cardElevation(6.dp)
) {
Row(
modifier = Modifier.padding(16.dp)
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Image(
painter = painterResource(id = car.images.first()),
contentDescription = car.name,
modifier = Modifier
.size(180.dp)
.clip(RoundedCornerShape(8.dp)),
contentScale = ContentScale.Fit
)
Spacer(modifier = Modifier.width(16.dp))
Column {
Text(car.name, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.headlineLarge)
Text(car.brand)
Text("Price: ₹${car.price}", style = MaterialTheme.typography.titleLarge)
// ⭐️ Display the rating
Row(verticalAlignment = Alignment.CenterVertically) {
StarRating(rating = car.rating)
StarRating(rating = car.rating)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = "${car.rating}",
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.secondary
)
}
}
}
}
}
}
}
}
Brand Screen
package com.codingbihar.carwala
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
@Composable
fun BrandCarsScreen(brand: String, cars: List<Car>,navController: NavController) {
val filteredCars = cars.filter { it.brand == brand }
Column(modifier = Modifier.fillMaxSize().systemBarsPadding()) {
Text(text = stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineLarge,
color = MaterialTheme.colorScheme.secondary,
fontWeight = FontWeight.ExtraBold
)
Text(
text = "Cars from $brand",
style = MaterialTheme.typography.headlineSmall,
modifier = Modifier.padding(bottom = 16.dp)
)
LazyColumn {
items(filteredCars) { car ->
CarListItem(car = car) {
// Navigate to detail screen if needed
navController.navigate("carDetail/${car.name}")
}
}
}
}
}
@Composable
fun CarListItem(car: Car, onClick: () -> Unit) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
.clickable { onClick() },
elevation = CardDefaults.cardElevation(4.dp)
) {
Row(modifier = Modifier.padding(16.dp)) {
Image(
painter = painterResource(id = car.images[0]),
contentDescription = car.name,
modifier = Modifier.size(130.dp),
contentScale = ContentScale.Fit
)
Spacer(modifier = Modifier.width(16.dp))
Column {
Text(
car.name,
style = MaterialTheme.typography.headlineSmall,
fontWeight = FontWeight.Bold
)
Text(car.brand, style = MaterialTheme.typography.bodyLarge)
Text(
"₹${car.price}",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
)
}
}
}
}
Rating Bar
package com.codingbihar.carwala
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Star
import androidx.compose.material.icons.filled.StarHalf
import androidx.compose.material.icons.outlined.Star
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
@Composable
fun StarRating(rating: Float) {
Row {
for (i in 1..5) {
when {
i <= rating -> {
Icon(
imageVector = Icons.Filled.Star,
contentDescription = null,
tint = Color.Blue,
modifier = Modifier.size(30.dp)
)
}
i - rating in 0.4..0.6 -> {
Icon(
imageVector = Icons.Filled.StarHalf,
contentDescription = null,
tint = Color.Blue,
modifier = Modifier.size(30.dp)
)
}
else -> {
Icon(
imageVector = Icons.Outlined.Star,
contentDescription = null,
tint = Color.LightGray,
modifier = Modifier.size(30.dp)
)
}
}
}
}
}
Car Data Model
package com.codingbihar.carwala
data class Car(
val name: String,
val brand: String,
val rating: Float, // e.g., 4.5
// val rating: Float = (3..5).random() + listOf(0f, 0.5f).random(),
val description: CarDescription, // <-- changed from Map to CarDescription
val images: List<Int>,
val price: Int // 👈 New field: Price in rupees
)
data class CarDescription(
val fuelType: String,
val engine: String,
val powerAndTorque: String,
val driveTrain: String,
val acceleration: String,
val topSpeed: String
)
val cars = listOf(
Car(
name = "Maruti Swift",
brand = "Maruti Suzuki",
rating = 2.5f,
images = listOf(R.drawable.maruti_swift),
price = 600000,
description = CarDescription(
fuelType = "Petrol",
engine = "1197 cc",
powerAndTorque = "89 bhp & 113 Nm",
driveTrain = "FWD",
acceleration = "12.5 seconds",
topSpeed = "165 kmph"
)
),
Car(
name = "Hyundai Creta",
brand = "Hyundai",
rating = 2.5f,
images = listOf(R.drawable.hyundai_creta),
price = 1100000,
description = CarDescription(
fuelType = "Petrol/Diesel",
engine = "1493 cc",
powerAndTorque = "113 bhp & 144 Nm",
driveTrain = "FWD",
acceleration = "10.5 seconds",
topSpeed = "190 kmph"
)
),
Car(
name = "Tata Nexon",
brand = "Tata Motors",
rating = 2.5f,
images = listOf(R.drawable.tata_nexon),
price = 950000,
description = CarDescription(
fuelType = "Petrol/Diesel",
engine = "1199 cc",
powerAndTorque = "118 bhp & 170 Nm",
driveTrain = "FWD",
acceleration = "11.5 seconds",
topSpeed = "180 kmph"
)
),
Car(
name = "Mahindra XUV700",
brand = "Mahindra",
rating = 2.5f,
images = listOf(R.drawable.mahindra),
price = 1600000,
description = CarDescription(
fuelType = "Petrol/Diesel",
engine = "1997 cc",
powerAndTorque = "200 bhp & 380 Nm",
driveTrain = "AWD",
acceleration = "9.5 seconds",
topSpeed = "200 kmph"
)
),
Car(
name = "Kia Seltos",
brand = "Kia",
rating = 2.5f,
images = listOf(R.drawable.kia_seltos),
price = 1050000,
description = CarDescription(
fuelType = "Petrol/Diesel",
engine = "1497 cc",
powerAndTorque = "113 bhp & 144 Nm",
driveTrain = "FWD",
acceleration = "10.8 seconds",
topSpeed = "185 kmph"
)
),
Car(
name = "Honda City",
brand = "Honda",
rating = 2.5f,
images = listOf(R.drawable.honda_city),
price = 1200000,
description = CarDescription(
fuelType = "Petrol",
engine = "1498 cc",
powerAndTorque = "119 bhp & 145 Nm",
driveTrain = "FWD",
acceleration = "10.0 seconds",
topSpeed = "195 kmph"
)
),
Car(
name = "Skoda Slavia",
brand = "Skoda",
rating = 2.5f,
images = listOf(R.drawable.skoda_slavia),
price = 1150000,
description = CarDescription(
fuelType = "Petrol",
engine = "999 cc",
powerAndTorque = "113 bhp & 178 Nm",
driveTrain = "FWD",
acceleration = "10.7 seconds",
topSpeed = "190 kmph"
)
),
Car(
name = "Volkswagen Taigun",
brand = "Volkswagen",
rating = 2.5f,
images = listOf(R.drawable.volkswagen_taigun),
price = 1400000,
description = CarDescription(
fuelType = "Petrol",
engine = "1498 cc",
powerAndTorque = "147 bhp & 250 Nm",
driveTrain = "FWD",
acceleration = "9.1 seconds",
topSpeed = "205 kmph"
)
),
Car(
name = "Toyota Fortuner",
brand = "Toyota",
rating = 2.5f,
images = listOf(R.drawable.toyota_fortuner),
price = 3500000,
description = CarDescription(
fuelType = "Diesel",
engine = "2755 cc",
powerAndTorque = "201 bhp & 500 Nm",
driveTrain = "4WD",
acceleration = "10.4 seconds",
topSpeed = "180 kmph"
)
),
Car(
name = "MG Hector",
brand = "MG Motors",
rating = 2.5f,
images = listOf(R.drawable.mg_hector),
price = 1500000,
description = CarDescription(
fuelType = "Petrol/Diesel",
engine = "1451 cc",
powerAndTorque = "141 bhp & 250 Nm",
driveTrain = "FWD",
acceleration = "11.2 seconds",
topSpeed = "175 kmph"
)
),
Car(
name = "Jeep Compass",
brand = "Jeep",
rating = 2.5f,
images = listOf(R.drawable.tata_nexon),
price = 2100000,
description = CarDescription(
fuelType = "Petrol/Diesel",
engine = "1368 cc",
powerAndTorque = "163 bhp & 250 Nm",
driveTrain = "4WD",
acceleration = "9.9 seconds",
topSpeed = "202 kmph"
)
),
Car(
name = "Ford Endeavour",
brand = "Ford",
rating = 2.5f,
images = listOf(R.drawable.mg_hector),
price = 3500000,
description = CarDescription(
fuelType = "Diesel",
engine = "1996 cc",
powerAndTorque = "210 bhp & 500 Nm",
driveTrain = "4WD",
acceleration = "9.8 seconds",
topSpeed = "180 kmph"
)
),
Car(
name = "Mercedes GLC",
brand = "Mercedes-Benz",
rating = 2.5f,
images = listOf(R.drawable.tata_nexon),
price = 6500000,
description = CarDescription(
fuelType = "Petrol/Diesel",
engine = "1991 cc",
powerAndTorque = "194 bhp & 320 Nm",
driveTrain = "AWD",
acceleration = "7.9 seconds",
topSpeed = "220 kmph"
)
),
Car(
name = "BMW X5",
brand = "BMW",
rating = 2.5f,
images = listOf(R.drawable.tata_nexon),
price = 9500000,
description = CarDescription(
fuelType = "Diesel",
engine = "2993 cc",
powerAndTorque = "265 bhp & 620 Nm",
driveTrain = "AWD",
acceleration = "6.5 seconds",
topSpeed = "230 kmph"
)
),
Car(
name = "Audi Q5",
brand = "Audi",
rating = 2.5f,
images = listOf(R.drawable.tata_nexon),
price = 7000000,
description = CarDescription(
fuelType = "Petrol",
engine = "1984 cc",
powerAndTorque = "249 bhp & 370 Nm",
driveTrain = "AWD",
acceleration = "6.3 seconds",
topSpeed = "237 kmph"
)
),
Car(
name = "Land Rover Discovery",
brand = "Land Rover",
rating = 2.5f,
images = listOf(R.drawable.kia_seltos),
price = 8800000,
description = CarDescription(
fuelType = "Diesel",
engine = "2997 cc",
powerAndTorque = "345 bhp & 700 Nm",
driveTrain = "AWD",
acceleration = "6.3 seconds",
topSpeed = "209 kmph"
)
),
Car(
name = "Volvo XC60",
brand = "Volvo",
rating = 2.5f,
images = listOf(R.drawable.tata_nexon),
price = 6700000,
description = CarDescription(
fuelType = "Petrol",
engine = "1969 cc",
powerAndTorque = "250 bhp & 350 Nm",
driveTrain = "AWD",
acceleration = "7.0 seconds",
topSpeed = "220 kmph"
)
),
Car(
name = "Porsche Cayenne",
brand = "Porsche",
rating = 2.5f,
images = listOf(R.drawable.tata_nexon),
price = 13000000,
description = CarDescription(
fuelType = "Petrol",
engine = "2995 cc",
powerAndTorque = "340 bhp & 450 Nm",
driveTrain = "AWD",
acceleration = "6.0 seconds",
topSpeed = "245 kmph"
)
),
Car(
name = "Tata Harrier",
brand = "Tata Motors",
rating = 2.5f,
images = listOf(R.drawable.tata_nexon),
price = 1500000,
description = CarDescription(
fuelType = "Diesel",
engine = "1956 cc",
powerAndTorque = "168 bhp & 350 Nm",
driveTrain = "FWD",
acceleration = "11.0 seconds",
topSpeed = "180 kmph"
)
),
Car(
name = "Renault Kiger",
brand = "Renault",
rating = 2.5f,
images = listOf(R.drawable.kia_seltos),
price = 700000,
description = CarDescription(
fuelType = "Petrol",
engine = "999 cc",
powerAndTorque = "99 bhp & 152 Nm",
driveTrain = "FWD",
acceleration = "12.7 seconds",
topSpeed = "170 kmph"
)
),
Car(
name = "Tata Punch EV",
brand = "Tata Motors",
rating = 3.5f,
images = listOf(R.drawable.tata_nexon),
price = 1050000,
description = CarDescription(
fuelType = "Electric",
engine = "NA",
powerAndTorque = "82 bhp & 114 Nm",
driveTrain = "FWD",
acceleration = "13.5 seconds",
topSpeed = "140 kmph"
)
)
)
Car Detail Screen
package com.codingbihar.carwala
import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
@Composable
fun CarDetailScreen(
carName: String,
navController: NavController,
cartViewModel: CartViewModel = viewModel()
) {
val car = cars.find { it.name == carName }
if (car == null) {
Text(
text = "Car not found",
modifier = Modifier.fillMaxSize(),
textAlign = TextAlign.Center
)
return
}
// Check if the car is already in cart
val isInCart = cartViewModel.cartItems.any { it.name == car.name }
val text = LocalContext.current
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
.verticalScroll(rememberScrollState()), // allow scrolling
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineLarge,
color = MaterialTheme.colorScheme.secondary,
fontWeight = FontWeight.ExtraBold
)
// Car Image
Image(
painter = painterResource(id = car.images.first()),
contentDescription = car.name,
contentScale = ContentScale.Fit,
modifier = Modifier
.height(330.dp)
.fillMaxWidth()
.clip(RoundedCornerShape(16.dp))
)
Spacer(modifier = Modifier.height(16.dp))
// Car Basic Info
Text(car.name, style = MaterialTheme.typography.headlineSmall, fontWeight = FontWeight.Bold)
Text(car.brand, style = MaterialTheme.typography.bodyLarge)
Text("₹${car.price}", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.height(24.dp))
// Description Card
Card(
modifier = Modifier
.fillMaxWidth(),
elevation = CardDefaults.cardElevation(6.dp)
) {
Column(modifier = Modifier.padding(16.dp)) {
Text("Specifications", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.height(8.dp))
TableRow(label = "Fuel Type", value = car.description.fuelType)
TableRow(label = "Engine", value = car.description.engine)
TableRow(label = "Power & Torque", value = car.description.powerAndTorque)
TableRow(label = "Drive Train", value = car.description.driveTrain)
TableRow(label = "Acceleration", value = car.description.acceleration)
TableRow(label = "Top Speed", value = car.description.topSpeed)
}
}
Spacer(modifier = Modifier.height(24.dp))
// Button: Add to Cart or Go to Cart
Button(
onClick = {
if (isInCart) {
navController.navigate("cart")
} else {
cartViewModel.addToCart(car)
Toast.makeText(text, "${car.name} added to cart", Toast.LENGTH_SHORT).show()
}
},
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
) {
Text(text = if (isInCart) "Go to Cart" else "Add to Cart")
}
Spacer(modifier = Modifier.height(16.dp))
}
}
// Helper for showing description in table row style
@Composable
fun TableRow(label: String, value: String) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(text = label, fontWeight = FontWeight.SemiBold)
Text(text = value)
}
}
Cart Screen
package com.codingbihar.carwala
import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun CartScreen(
cartViewModel: CartViewModel = viewModel()
) {
val cartItems = cartViewModel.cartItems
val totalPrice = cartViewModel.totalPrice
val context = LocalContext.current
Column(modifier = Modifier.systemBarsPadding(),
) {
Text(text = stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineLarge,
color = MaterialTheme.colorScheme.secondary,
fontWeight = FontWeight.ExtraBold
)
Text("Your Cart", style = MaterialTheme.typography.headlineMedium, fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.height(16.dp))
LazyColumn {
items(cartItems) { car ->
Card(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
elevation = CardDefaults.cardElevation(6.dp)
) {
Row(modifier = Modifier.padding(16.dp)) {
Image(
painter = painterResource(id = car.images.first()),
contentDescription = car.name,
modifier = Modifier.size(80.dp)
)
Spacer(modifier = Modifier.width(16.dp))
Column {
Text(car.name, fontWeight = FontWeight.Bold)
Text(car.brand)
Text("₹${car.price}")
}
}
}
}
}
Spacer(modifier = Modifier.height(24.dp))
Box(Modifier.fillMaxWidth().weight(1f),
contentAlignment = Alignment.BottomCenter
){
Spacer(modifier = Modifier.height(16.dp))
Text("Total: ₹$totalPrice", fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.height(24.dp))
Button(
onClick = {
Toast.makeText(context, "Please enter your name", Toast.LENGTH_SHORT).show()
},
modifier = Modifier.fillMaxWidth()
) {
Text("Place Order")
}
}
}
}
Cart View Model
package com.codingbihar.carwala
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
class CartViewModel : ViewModel() {
private val _cartItems = mutableStateListOf<Car>()
val cartItems: List<Car> get() = _cartItems
var totalPrice by mutableIntStateOf(0)
private set
fun addToCart(car: Car) {
_cartItems.add(car)
updateTotalPrice()
}
fun clearCart() {
_cartItems.clear()
updateTotalPrice()
}
private fun updateTotalPrice() {
totalPrice = _cartItems.sumOf { it.price }
}
}