Basic list one
Use items to load data in the LazyColumn component, and rememberLazyListState() combined with rememberCoroutineScope() returns to the top.
/** *Basic list one */ @Composable funItems() { Box(modifier = Modifier.fillMaxSize()) { val context = LocalContext.current val dataList = arrayListOf<Int>() for (index in 1..50) { dataList.add(index) } val listState = rememberLazyListState() LazyColumn(state = listState) { items(dataList) { data -> Text( text = "No. ${data} data", textAlign = TextAlign.Center, //The running effect will be different if the order of property setting is different. modifier = Modifier .fillMaxWidth() .padding(top = 1.dp) .background(Color.White) .clickable { Toast .makeText(context, "$data", Toast.LENGTH_SHORT) .show() } .padding(10.dp) ) } } //Back to top val coroutineScope = rememberCoroutineScope() Image( modifier = Modifier .padding(end = 10.dp, bottom = 10.dp) .width(45.dp) .height(45.dp) .clip(CircleShape) .align(Alignment.BottomEnd) .background(Color.Blue) .clickable { coroutineScope.launch { listState.animateScrollToItem(index = 0) } }, painter = painterResource(id = R.drawable.top), contentDescription = "Back to top icon" ) } }
Basic List 2
Data is loaded in LazyColumn through the itemsIndexed attribute.
/** *Basic list two */ @Composable fun ItemsIndexed() { val context = LocalContext.current val stringList = arrayListOf<String>() for (index in 1..50) { stringList.add(index.toString()) } LazyColumn { //stringList.toArray() method can convert List to Array through List's toArray method itemsIndexed(stringList) { index, data -> Text( text = "My index is: ${index}, my data is: $data", textAlign = TextAlign.Center, modifier = Modifier .fillMaxWidth() .padding(top = 1.dp) .background(Color.White) .clickable { Toast .makeText(context, data, Toast.LENGTH_SHORT) .show() } ) } } }
Multiple Type List
Load different layouts based on different data types.
/** *Multiple Type list */ @Composable fun AnyTypeList() { val charList = arrayListOf<Chat>() charList.apply { add(Chat("Hello")) add(Chat("What are you doing")) add(Chat("I want to ask you something")) add(Chat("Nothing done, still writing code!", false)) add(Chat("What's the matter, brother?", false)) add(Chat("It's okay...")) add(Chat("Okay...", false)) } LazyColumn { items(charList) { data -> if (data.isLeft) { Column( modifier = Modifier .fillMaxWidth() .padding(start = 10.dp) ) { //Interval setting Spacer(modifier = Modifier.height(10.dp)) Row( verticalAlignment = Alignment.CenterVertically ) { Image( modifier = Modifier .width(35.dp) .height(35.dp) //Cut the circle .clip(CircleShape), painter = painterResource(id = R.drawable.ic_launcher_background), contentDescription = "Left avatar" ) Spacer(modifier = Modifier.width(10.dp)) Text( data.content, modifier = Modifier .wrapContentWidth() .background(Color.Yellow) .padding(10.dp), ) } } } else { Column( modifier = Modifier .fillMaxWidth() .padding(end = 10.dp), horizontalAlignment = Alignment.End ) { Spacer(modifier = Modifier.height(10.dp)) Row( verticalAlignment = Alignment.CenterVertically ) { Text( data.content, modifier = Modifier .wrapContentWidth() .background(Color.Green) .padding(10.dp) ) Spacer(modifier = Modifier.width(10.dp)) Image( modifier = Modifier .width(35.dp) .height(35.dp) .clip(CircleShape), painter = painterResource(id = R.drawable.ic_launcher_background), contentDescription = "right avatar" ) } } } } } }
Data class:
/** * created by cwj on 2023-10-16 * Description: Multi-type list class */ data class Chat(val content: String, val isLeft: Boolean = true)
Sticky title list
Use sticky header stickyHeader component. When the list slides, the first-level title is suspended at the top. As the list slides and the first-level list slides out and is replaced, a first-level title remains suspended at the top.
/** * Sticky title list */ @OptIn(ExperimentalFoundationApi::class) @Composable fun StickyHeaderTest() { val context = LocalContext.current val letters = arrayListOf("Type One", "Type Two", "Type Three", "Type Four", "Type Five") val contactList = arrayListOf<Contact>() val nameList = arrayListOf<String>() for (index in 1..5) { nameList.add("subitem$index") } for (index in letters.iterator()) { contactList.add(Contact(letters = index, nameList)) } LazyColumn { contactList.forEach { (letter, nameList) -> stickyHeader { Text( text = letter, modifier = Modifier .background(Color.LightGray) .padding(start = 10.dp) .fillMaxWidth(), fontSize = 25.sp ) } items(nameList) { contact -> Text( text = contact, modifier = Modifier .padding(10.dp) .background(Color.White) .fillMaxWidth() .clickable { Toast .makeText(context, contact, Toast.LENGTH_SHORT) .show() }, textAlign = TextAlign.Center, fontSize = 25.sp ) } } } }
Data classes that can correspond to sticky titles and list data:
/** * created by cwj on 2023-10-17 * Description: A data class that can correspond to sticky titles and list data */ data class Contact(val letters: String, val nameList: List<String>)
Complete code:
import android.os.Bundle import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable 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.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource 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 com.cwj.composedemo.ui.theme.ComposeDemoTheme import kotlinx.coroutines.launch class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { ComposeDemoTheme { // A surface container using the 'background' color from the theme Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { Greeting() } } } } } @Composable funGreeting() { //Items() //ItemsIndexed() //AnyTypeList() StickyHeaderTest() } /** * Sticky title list */ @OptIn(ExperimentalFoundationApi::class) @Composable fun StickyHeaderTest() { val context = LocalContext.current val letters = arrayListOf("Type One", "Type Two", "Type Three", "Type Four", "Type Five") val contactList = arrayListOf<Contact>() val nameList = arrayListOf<String>() for (index in 1..5) { nameList.add("subitem$index") } for (index in letters.iterator()) { contactList.add(Contact(letters = index, nameList)) } LazyColumn { contactList.forEach { (letter, nameList) -> stickyHeader { Text( text = letter, modifier = Modifier .background(Color.LightGray) .padding(start = 10.dp) .fillMaxWidth(), fontSize = 25.sp ) } items(nameList) { contact -> Text( text = contact, modifier = Modifier .padding(10.dp) .background(Color.White) .fillMaxWidth() .clickable { Toast .makeText(context, contact, Toast.LENGTH_SHORT) .show() }, textAlign = TextAlign.Center, fontSize = 25.sp ) } } } } /** *Multiple Type list */ @Composable fun AnyTypeList() { val charList = arrayListOf<Chat>() charList.apply { add(Chat("Hello")) add(Chat("What are you doing")) add(Chat("I want to ask you something")) add(Chat("Nothing done, still writing code!", false)) add(Chat("What's the matter, brother?", false)) add(Chat("It's okay...")) add(Chat("Okay...", false)) } LazyColumn { items(charList) { data -> if (data.isLeft) { Column( modifier = Modifier .fillMaxWidth() .padding(start = 10.dp) ) { //Interval setting Spacer(modifier = Modifier.height(10.dp)) Row( verticalAlignment = Alignment.CenterVertically ) { Image( modifier = Modifier .width(35.dp) .height(35.dp) //Cut the circle .clip(CircleShape), painter = painterResource(id = R.drawable.ic_launcher_background), contentDescription = "Left avatar" ) Spacer(modifier = Modifier.width(10.dp)) Text( data.content, modifier = Modifier .wrapContentWidth() .background(Color.Yellow) .padding(10.dp), ) } } } else { Column( modifier = Modifier .fillMaxWidth() .padding(end = 10.dp), horizontalAlignment = Alignment.End ) { Spacer(modifier = Modifier.height(10.dp)) Row( verticalAlignment = Alignment.CenterVertically ) { Text( data.content, modifier = Modifier .wrapContentWidth() .background(Color.Green) .padding(10.dp) ) Spacer(modifier = Modifier.width(10.dp)) Image( modifier = Modifier .width(35.dp) .height(35.dp) .clip(CircleShape), painter = painterResource(id = R.drawable.ic_launcher_background), contentDescription = "right avatar" ) } } } } } } /** *Basic list two */ @Composable fun ItemsIndexed() { val context = LocalContext.current val stringList = arrayListOf<String>() for (index in 1..50) { stringList.add(index.toString()) } LazyColumn { //stringList.toArray() method can convert List to Array through List's toArray method itemsIndexed(stringList) { index, data -> Text( text = "My index is: ${index}, my data is: $data", textAlign = TextAlign.Center, modifier = Modifier .fillMaxWidth() .padding(top = 1.dp) .background(Color.White) .clickable { Toast .makeText(context, data, Toast.LENGTH_SHORT) .show() } ) } } } /** *Basic list one */ @Composable funItems() { Box(modifier = Modifier.fillMaxSize()) { val context = LocalContext.current val dataList = arrayListOf<Int>() for (index in 1..50) { dataList.add(index) } val listState = rememberLazyListState() LazyColumn(state = listState) { items(dataList) { data -> Text( text = "No. ${data} data", textAlign = TextAlign.Center, //The running effect will be different if the order of property setting is different. modifier = Modifier .fillMaxWidth() .padding(top = 1.dp) .background(Color.White) .clickable { Toast .makeText(context, "$data", Toast.LENGTH_SHORT) .show() } .padding(10.dp) ) } } //Back to top val coroutineScope = rememberCoroutineScope() Image( modifier = Modifier .padding(end = 10.dp, bottom = 10.dp) .width(45.dp) .height(45.dp) .clip(CircleShape) .align(Alignment.BottomEnd) .background(Color.Blue) .clickable { coroutineScope.launch { listState.animateScrollToItem(index = 0) } }, painter = painterResource(id = R.drawable.top), contentDescription = "Back to top icon" ) } } @Preview(showBackground = true, showSystemUi = true) @Composable fun GreetingPreview() { ComposeDemoTheme { Greeting() } }