androidkotlinandroid-jetpack-composescrollablelazycolumn

Using Horizontal LazyRow with items in compose


I am trying to figure out what would be the best approach to create this type of design: https://gyazo.com/bae04894f7ef079a06ad71f733026f33

https://gyazo.com/111eace0d8cdecdecad1c8a7b486faf7

Should I be using a Horizontal lazyRow as suggested with a scrollview or how would I go about doing this? Should I also create 1 composable for each item in placeholdercard or is there a more efficient way to do this with the newer version of jetpack compose? Appreciate the feedback!

This is the code so far:


@Composable
fun MainContent(
    placeholderItems: List<String>
) {

    val lazyListState: LazyListState = rememberLazyListState()

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {

        Text(
            modifier = Modifier
                .padding(16.dp)
                .fillMaxWidth(),
            text = "Example Horizontal LazyRow"
        )

        LazyRow(
            modifier = Modifier.fillMaxWidth(),
            contentPadding = PaddingValues(8.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {

            items(items = placeholderItems) { itemMessage: String ->
                PlaceholderCard(itemMessage)
            }
        }
    }
}

Updated Answer This managed to solve the issues! Thanks to:
@Sadegh.t for suggesting it! - Had to do some tweeks but now it works fully!


data class Items(
    val num: Int,
    val id: UUID = UUID.randomUUID()
)

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ItemView(modifier: Modifier = Modifier, title: String, selected:
Boolean = false) {
    Card(
        modifier = if (!selected) modifier
            .height(80.dp)
            .width(95.dp)
        else modifier
            .height(100.dp)
            .width(120.dp),
        shape = RoundedCornerShape(16.dp),
        elevation = if (selected) CardDefaults.cardElevation(24.dp ) else CardDefaults.cardElevation(4.dp)
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically
        ) {

            Text(text = title, modifier = Modifier.fillMaxWidth()
                , textAlign =  TextAlign.Center)
        }
    }
}

@Composable
fun NumberList(list: List<Items>) {

    Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {

        LazyRow(state = rememberLazyListState()) {

            items(50, key = { it }) {
                if (it == 2) {
                    ItemView(
                        title = it.toString(),
                        modifier = Modifier
                            .padding(start = 16.dp, end = 8.dp, bottom = 16.dp, top = 8.dp)
                            .fillMaxWidth()
                            .height(80.dp)
                        , selected = true
                    )
                }else {
                    ItemView(
                        title = it.toString(),
                        modifier = Modifier
                            .padding(start = 16.dp, end = 8.dp, bottom = 16.dp, top = 8.dp)
                            .fillMaxWidth()
                    )
                }
            }
        }
    }
}


Solution

  • You can try this, create a LazyRow and then check if the item is selected or not

    @Composable 
    fun NumberList(list: List<Items>) {
        Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
            LazyRow(state = rememberLazyListState()) {
                items(list, key = { it.id }) {
                    if (it.num == 2) {
                        ItemView(
                            title = it.num.toString(),
                            modifier = Modifier
                                .padding(start = 16.dp, end = 8.dp, bottom = 16.dp, top = 8.dp)
                                .fillMaxWidth()
                                .height(80.dp)
                        , selected = true
                        )
                    }else {
                        ItemView(
                            title = it.num.toString(),
                            modifier = Modifier
                                .padding(start = 16.dp, end = 8.dp, bottom = 16.dp, top = 8.dp)
                                .fillMaxWidth()
                        )
                    }
                }
            }
        }
    }
    

    and for the item:

    @Composable
    fun ItemView(modifier: Modifier = Modifier, title: String, selected: 
        Boolean = false) {
        Card(
            modifier = if (!selected) modifier
                .height(80.dp)
                .width(95.dp)
            else modifier
                .height(100.dp)
                .width(120.dp),
            shape = RoundedCornerShape(16.dp),
            elevation = if (selected) 24.dp else 4.dp
        ) {
            Row(
                modifier = Modifier.fillMaxWidth(),
                verticalAlignment = Alignment.CenterVertically
            ) {
    
                Text(text = title, modifier = Modifier.fillMaxWidth()
                , textAlign =  TextAlign.Center)
            }
        }
    }
    

    Updated: I used this data class you can use your own data class, also it's not necessary to use the Id.

    data class Items(val num: Int, val id: UUID = UUID.randomUUID())