SqueezeOJ
SqueezeOJ

Reputation: 527

How to Recompose Simple LazyColumn List Example

I'm new to Jetpack Compose and I'm trying to figure out how to recompose a LazyColumn list when user clicks a FloatingActionButton.

As the picture shows, I have a basic Scaffold layout with a LazyColumn for content. Toward the bottom is a FloatingActionButton. I'd like to be able to click that FloatingActionButton, add "Molly" to my list of names, have the app recompose my list, and display the full list including Molly. Code below picture.

enter image description here


Here's my code:

package com.learning.lazylistexample

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import com.learning.lazylistexample.ui.theme.LazyListExampleTheme
import kotlinx.coroutines.launch

data class ListItem(val name: String)

private var listItems: MutableList<ListItem> = mutableListOf(
    ListItem("Al"),
    ListItem("Barb"),
    ListItem("Cheryl"),
    ListItem("Dave"),
    ListItem("Ed"),
    ListItem("Frank"),
    ListItem("Gloria"),
    ListItem("Henry"),
    ListItem("Ingrid"),
    ListItem("Jack"),
    ListItem("Kayla"),
    ListItem("Larry")
)

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            LazyListExampleTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    myApp()
                }
            }
        }
    }
}

@Composable
fun myApp() {

    val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))

    val coroutineScope = rememberCoroutineScope()

    Scaffold(
        scaffoldState = scaffoldState,
        topBar = { TopBar() },
        bottomBar = { BottomBar() },
        content = { DisplayList(itemsList = listItems) },
        floatingActionButton = {
            FloatingActionButton(

                onClick = {
                    // When clicked open Snackbar
                    coroutineScope.launch {
                        when (scaffoldState.snackbarHostState.showSnackbar(
                            // Message In the snack bar
                            message = "Snack Bar",
                            actionLabel = "Dismiss"
                        )) {
                            SnackbarResult.Dismissed -> {
                                // do something when snack bar is dismissed
                            }

                            SnackbarResult.ActionPerformed -> {
                                // do something when snack bar is activated
                                // ****** UPDATE LIST *******
                                val newListItem = ListItem(name = "Molly")
                                listItems.add(newListItem)
                                // ****** HOW TO RECOMPOSE LAZYCOLUMN? ******
                            }
                        }
                    }
                }) {
                // Text inside FloatingActionButton
                Text(text = "Add Molly")
            }
        }

    )

}

@Composable
fun TopBar() {
    TopAppBar(
        title = { Text(text = "Lazy List Example", color = Color.White) }
    )
}

@Composable
fun BottomBar() {
    BottomAppBar() {
        Text(text = "", color = Color.White)
    }
}

@Composable
fun DisplayList(itemsList: List<ListItem>) {
    LazyColumn(modifier = Modifier.fillMaxHeight()) {
        items(items = itemsList, itemContent = { item ->
            Text(text = item.name)
        } )
    }
}

I know this has something to do with state, but I can't figure out where to begin. Can anyone help me with this?

THANK YOU!

Upvotes: 3

Views: 3219

Answers (1)

Thracian
Thracian

Reputation: 67179

Change

private var listItems: MutableList<ListItem> = mutableListOf(
    ListItem("Al"),
    ListItem("Barb"),
    ListItem("Cheryl"),
    ListItem("Dave"),
    ListItem("Ed"),
    ListItem("Frank"),
    ListItem("Gloria"),
    ListItem("Henry"),
    ListItem("Ingrid"),
    ListItem("Jack"),
    ListItem("Kayla"),
    ListItem("Larry")
)

to

val listItems = remember { mutableStateListOf(
     ListItem("Al"),
        ListItem("Barb"),
        ListItem("Cheryl"),
        ListItem("Dave"),
        ListItem("Ed"),
        ListItem("Frank"),
        ListItem("Gloria"),
        ListItem("Henry"),
        ListItem("Ingrid"),
        ListItem("Jack"),
        ListItem("Kayla"),
        ListItem("Larry")
) }

And you will have a SnapshotStateList, an instance of MutableList that is observable and can be snapshot, that will trigger recomposition when you add or remove any items.

Upvotes: 5

Related Questions