Wednesday, April 28, 2021

jetpack compose - LazyColumn add remove item

Compose LazyColumn Add Remove Item
The LazyColumn is an equivalent widget of RecyclerView. But there is no adapter for LazyColumn. Like RecyclerView, LazyColumn does not need any adapter to populate items. In this case, we can show items in a LazyColumn widget using a simple list. Yes, we talked about the jetpack compose library LazyColumn widget.

LazyColumn shows a vertically scrollable list of items. This is super fast and took a much smaller memory size. The items are composed when they are in a visible state in a LazyColumn. As with adding a list to the LazyColumn items collection we can even add a single item to the LazyColumn.

The following android jetpack compose tutorial code will describe to us how we can add and remove an item from LayColumn. To do this, we create a mutable list of string values which we generate from a random UUID. We also remember the items of the mutable list using the jetpack compose library API. To generate LazyColumn items we used its LazyListScope.itemsIndexed() inline function and pass the mutable list as its argument. So our LazyColumn now shows items on it and they have an index associated with it.

This index number helps us to identify the LazyCoumn specified item from the mutable list. We know we can add and remove an item from a mutable list. Those are the important properties of a mutable list. So when we add an item to the mutable list, its ‘remember’ feature also updates the LazyColumn and shows the newly added item to its items collection. The same thing happened when we remove an item from the mutable list, the LazyColumn instantly remove/delete the associated item from its list.

In this kotlin tutorial, we put a remove button inside each item of LazyColumn. So, when an app user click’s the remove button it removes the associated item from the mutable list and LazyColumn also updates its internal list. We can properly identify the LazyColumn associated mutable list item using its index number. Jetpack compose library AnimatedVisibility animates the visibility of the LazyColumn items.

Copy the code directly from here and paste it into your android studio IDE main activity file. Compile the code and run the generated apk to an emulator device, so you can test the LazyColumn item’s add and remove functionality in your hand. The following screenshots help you to understand the LazyColumn add and remove techniques without writing the code in your android studio IDE.
MainActivity.kt

package com.cfsuman.jetpackcompose

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import java.util.*

class MainActivity : AppCompatActivity() {
    @ExperimentalAnimationApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MainContent()
        }
    }


    @ExperimentalAnimationApi
    @Composable
    fun MainContent(){
        Box(
            Modifier
                .background(Color(0xFFEDEAE0))
                .fillMaxSize()
                .padding(8.dp)
        ) {
            val uuids = remember { mutableStateListOf<String>() }

            LazyColumn(
                Modifier.fillMaxSize(),
                verticalArrangement = Arrangement.spacedBy(8.dp)
            ) {
                itemsIndexed(uuids) { index, item ->
                    val visibility by remember {
                        mutableStateOf(
                            uuids.contains(item) && item == uuids[index]
                        )
                    }

                    AnimatedVisibility(
                        visible = visibility
                    ) {
                        Card(
                            modifier = Modifier
                                .fillMaxWidth()
                                .wrapContentHeight(
                                    align = Alignment.CenterVertically
                                ),
                            elevation = 4.dp,
                            shape = RoundedCornerShape(8.dp),
                            backgroundColor = if (index % 2 == 0)
                                Color(0xFF8DB600) else
                                    Color(0xFF48BF91)
                        ) {
                            Column(
                                modifier = Modifier
                                    .fillMaxSize()
                                    .padding(12.dp),
                                horizontalAlignment =
                                    Alignment.CenterHorizontally,
                                verticalArrangement =
                                    Arrangement.spacedBy(8.dp)
                            ) {
                                Text(
                                    text = item.take(5).capitalize(),
                                    modifier = Modifier.padding(
                                        start = 12.dp, top = 12.dp,
                                        end = 12.dp, bottom = 4.dp
                                    ),
                                    textAlign = TextAlign.Center,
                                    fontSize = 30.sp,
                                    fontWeight = FontWeight.Bold,
                                    color = Color.White
                                )
                                TextButton(
                                    onClick = { uuids.removeAt(index) },
                                    colors = ButtonDefaults.textButtonColors(
                                        backgroundColor = Color(0xFF960018),
                                        contentColor = Color.White
                                    )
                                ) {
                                    Text(text = "Remove")
                                }
                            }
                        }
                    }

                }
            }

            FloatingActionButton(
                onClick = {
                    UUID.randomUUID().toString().apply {
                        uuids.add(this)
                    }
                },
                Modifier.align(Alignment.BottomEnd),
                backgroundColor = Color(0xFFFE4164)
            ) { Icon(Icons.Filled.Add,"") }
        }
    }


    @Preview
    @Composable
    fun ComposablePreview(){
        //MainContent()
    }
}