Compose Shopping Cart Category List

Shopping cart app category list UI Design for Jetpack Compose UI UX.

Inspirational designs, and graphic elements from the world’s best designers.

Let us create 'Shopping cart app category list ' UI UX  in Jetpack Compose using  kotlin.

To create a data class ProductModel.kt (it has title, price, image & color code values)

we added some list of data source in our data class function getData().

package compose.material.theme

import androidx.annotation.DrawableRes
import androidx.compose.ui.graphics.Color

data class ProductModel(
    val title: String,
    val price: String,
    @DrawableRes
    val image: Int,
    val color: Color
)

fun getData(): List<ProductModel> {
    return listOf(
        ProductModel("Beats Solo 1","$223.00", R.drawable.headset4, Color(0xFFFF1A9B)),
        ProductModel("Beats Solo 2","$223.00", R.drawable.headset1, Color(0xFF5C00FF)),
        ProductModel("Beats Solo 3","$223.00", R.drawable.headset2, Color(0xFFFF0000)),
        ProductModel("Beats Solo 4","$223.00", R.drawable.headset3, Color(0xFF447ACE)),
        ProductModel("Beats Solo 5","$223.00", R.drawable.headset4, Color(0xFFFF1A9B)),
        ProductModel("Beats Solo 6","$223.00", R.drawable.headset1, Color(0xFF5C00FF)),
        ProductModel("Beats Solo 7","$223.00", R.drawable.headset2, Color(0xFFFF0000)),
        ProductModel("Beats Solo 8","$223.00", R.drawable.headset3, Color(0xFF447ACE)),
    )
}

..

To create Header() Composable function in Header.kt (it has image view, title & sub description text view)

package compose.material.theme

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
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.unit.dp

@Composable
fun Header() {
    Column {
        Image(
            painter = painterResource(id = R.drawable.header),
            contentDescription = null,
            contentScale = ContentScale.FillHeight,
            modifier = androidx.compose.ui.Modifier
                .height(120.dp)
                .padding(end = 32.dp)
        )

        Spacer(modifier = Modifier.height(10.dp))

        Text(text = "Beasts Products",
            style = MaterialTheme.typography.headlineLarge,
            color = MaterialTheme.colorScheme.onPrimary
        )
        Text(text = "Discover a new products from us",
            style = MaterialTheme.typography.headlineSmall,
            color = MaterialTheme.colorScheme.onPrimary
        )
    }
}

..

Now create a card view product view in ProductsCard.kt page

We created the enum class to hold touched & un-touched state of user click action on card view (to make scale & color alpha effect to our product view).

When user click on product we are changing animating visibility of price text view to Buy now text view.

package compose.material.theme

import android.view.MotionEvent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ArrowForward
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

enum class TouchState {
    Touched, NotTouched
}

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun ProductsCard(products: ProductModel) {

    var currentState: TouchState by remember { mutableStateOf(TouchState.NotTouched) }

    val transition = updateTransition(targetState = currentState, label = "animation")


    val scale: Float by transition.animateFloat(
        transitionSpec = { spring(stiffness = 900f) }, label = ""
    ) { state ->
        if (state == TouchState.Touched) {
            1.3f
        } else {
            1f
        }
    }

    val colorAlpha: Float by transition.animateFloat(
        transitionSpec = { spring(stiffness = 900f) }, label = ""
    ) { state ->
        if (state == TouchState.Touched) {
            1f
        } else {
            0.2f
        }
    }


    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(180.dp),
        contentAlignment = Alignment.BottomCenter
    ) {
        Card(
            Modifier
                .fillMaxWidth()
                .height(120.dp)
                .pointerInteropFilter {
                    currentState = when (it.action) {
                        MotionEvent.ACTION_DOWN -> {
                            TouchState.Touched
                        }
                        else -> {
                            TouchState.NotTouched
                        }
                    }
                    true
                },
            shape = RoundedCornerShape(topStart = 16.dp, bottomEnd = 16.dp, topEnd = 5.dp, bottomStart = 5.dp),
            backgroundColor = products.color.copy(alpha = 0.2f) ,
            elevation = 0.dp
        ) {
            Row(
                modifier = Modifier
                    .matchParentSize()
                    .background(
                        Brush.linearGradient(
                            colors = listOf(
                                products.color.copy(alpha = 0.2f),
                                products.color.copy(alpha = 0.2f),
                                products.color.copy(alpha = colorAlpha),
                            )
                        )
                    )
            ) {
                Column(
                    modifier = Modifier
                        .fillMaxHeight()
                        .padding(start = 32.dp),
                    horizontalAlignment = Alignment.Start,
                    verticalArrangement = Arrangement.Center
                ) {

                    Text(text = products.title,
                        letterSpacing =1.sp,
                        color = MaterialTheme.colorScheme.onPrimary,
                        style = MaterialTheme.typography.headlineSmall)
                    Spacer(modifier = Modifier.height(8.dp))

                    AnimatedVisibility(visible = currentState == TouchState.NotTouched) {
                        Text(
                            text = products.price,
                            letterSpacing =2.sp,
                            color = MaterialTheme.colorScheme.onPrimary,
                            style = MaterialTheme.typography.bodyMedium,
                        )
                    }
                    AnimatedVisibility(visible = currentState == TouchState.Touched) {
                        Row(verticalAlignment = Alignment.Bottom) {
                            Text(
                                text = "Buy Now",
                                style = MaterialTheme.typography.bodyMedium,
                                color = MaterialTheme.colorScheme.onPrimary,
                                letterSpacing =2.sp
                            )
                            Icon(imageVector = Icons.Rounded.ArrowForward, contentDescription = null, Modifier.size(20.dp))
                        }
                    }
                }
            }
        }

        Image(
            painter = painterResource(id = products.image),
            contentDescription = null,
            contentScale = ContentScale.FillHeight,
            modifier = Modifier
                .height((110 * scale).dp)
                .padding(end = 32.dp)
                .align(Alignment.BottomEnd)
        )
    }
}

..

In our MainActivity.kt we are making list view of our getData() from data source.

package compose.material.theme

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import compose.material.theme.ui.theme.Material3ComposeTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Material3ComposeTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = androidx.compose.material3.MaterialTheme.colorScheme.background
                ) {
                    MainScreen()
                }
            }
        }
    }
}

@Composable
fun MainScreen() {
    LazyColumn(
        verticalArrangement = Arrangement.spacedBy((-30).dp),
        contentPadding = PaddingValues(vertical = 24.dp, horizontal = 24.dp),
        content = {
            item {
                Header()
            }
            items(getData()) {
                ProductsCard(it)
            }
        })
}

..

..

..
..


Comments