LazyColumn组件中用items加载数据,rememberLazyListState()结合rememberCoroutineScope()实现返回顶部。
/**
* 基础列表一
*/
@Composable
fun Items() {
Box(modifier = Modifier.fillMaxSize()) {
val context = LocalContext.current
val dataList = arrayListOf()
for (index in 1..50) {
dataList.add(index)
}
val listState = rememberLazyListState()
LazyColumn(state = listState) {
items(dataList) { data ->
Text(
text = "第${data}条数据",
textAlign = TextAlign.Center,
//属性设置先后顺序不一样运行效果会不一样
modifier = Modifier
.fillMaxWidth()
.padding(top = 1.dp)
.background(Color.White)
.clickable {
Toast
.makeText(context, "$data", Toast.LENGTH_SHORT)
.show()
}
.padding(10.dp)
)
}
}
//返回顶部
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 = "返回顶部图标"
)
}
}
LazyColumn中通过itemsIndexed属性加载数据。
/**
* 基础列表二
*/
@Composable
fun ItemsIndexed() {
val context = LocalContext.current
val stringList = arrayListOf()
for (index in 1..50) {
stringList.add(index.toString())
}
LazyColumn {
//stringList.toArray()方法可以通过List的toArray方法将List转为Array
itemsIndexed(stringList) { index, data ->
Text(
text = "我的下标是:${index},我的数据为:$data",
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()
.padding(top = 1.dp)
.background(Color.White)
.clickable {
Toast
.makeText(context, data, Toast.LENGTH_SHORT)
.show()
}
)
}
}
}
根据不同数据类型加载不同布局。
/**
* 多Type列表
*/
@Composable
fun AnyTypeList() {
val charList = arrayListOf()
charList.apply {
add(Chat("你好啊"))
add(Chat("你在干啥呢"))
add(Chat("想问你个事"))
add(Chat("没干啥,还在写代码啊!", false))
add(Chat("啥事啊大哥?", false))
add(Chat("没事。。。"))
add(Chat("好吧。。。", false))
}
LazyColumn {
items(charList) { data ->
if (data.isLeft) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(start = 10.dp)
) {
//间隔设置
Spacer(modifier = Modifier.height(10.dp))
Row(
verticalAlignment = Alignment.CenterVertically
) {
Image(
modifier = Modifier
.width(35.dp)
.height(35.dp)
//裁剪圆形
.clip(CircleShape),
painter = painterResource(id = R.drawable.ic_launcher_background),
contentDescription = "左头像"
)
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 = "右头像"
)
}
}
}
}
}
}
数据类:
/**
* created by cwj on 2023-10-16
* Description:多类型列表类
*/
data class Chat(val content: String, val isLeft: Boolean = true)
使用粘性标题stickyHeader组件。滑动列表,一级标题悬浮顶部,随着列表滑动顶部一级列表滑出被替换,顶部一直保持一项一级标题悬浮。
/**
* 粘性标题列表
*/
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun StickyHeaderTest() {
val context = LocalContext.current
val letters = arrayListOf("类型一", "类型二", "类型三", "类型四", "类型五")
val contactList = arrayListOf()
val nameList = arrayListOf()
for (index in 1..5) {
nameList.add("子项$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
)
}
}
}
}
黏性标题和列表数据能对应起来的数据类:
/**
* created by cwj on 2023-10-17
* Description:黏性标题和列表数据能对应起来的数据类
*/
data class Contact(val letters: String, val nameList: List)
完整代码:
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
fun Greeting() {
// Items()
// ItemsIndexed()
// AnyTypeList()
StickyHeaderTest()
}
/**
* 粘性标题列表
*/
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun StickyHeaderTest() {
val context = LocalContext.current
val letters = arrayListOf("类型一", "类型二", "类型三", "类型四", "类型五")
val contactList = arrayListOf()
val nameList = arrayListOf()
for (index in 1..5) {
nameList.add("子项$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
)
}
}
}
}
/**
* 多Type列表
*/
@Composable
fun AnyTypeList() {
val charList = arrayListOf()
charList.apply {
add(Chat("你好啊"))
add(Chat("你在干啥呢"))
add(Chat("想问你个事"))
add(Chat("没干啥,还在写代码啊!", false))
add(Chat("啥事啊大哥?", false))
add(Chat("没事。。。"))
add(Chat("好吧。。。", false))
}
LazyColumn {
items(charList) { data ->
if (data.isLeft) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(start = 10.dp)
) {
//间隔设置
Spacer(modifier = Modifier.height(10.dp))
Row(
verticalAlignment = Alignment.CenterVertically
) {
Image(
modifier = Modifier
.width(35.dp)
.height(35.dp)
//裁剪圆形
.clip(CircleShape),
painter = painterResource(id = R.drawable.ic_launcher_background),
contentDescription = "左头像"
)
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 = "右头像"
)
}
}
}
}
}
}
/**
* 基础列表二
*/
@Composable
fun ItemsIndexed() {
val context = LocalContext.current
val stringList = arrayListOf()
for (index in 1..50) {
stringList.add(index.toString())
}
LazyColumn {
//stringList.toArray()方法可以通过List的toArray方法将List转为Array
itemsIndexed(stringList) { index, data ->
Text(
text = "我的下标是:${index},我的数据为:$data",
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()
.padding(top = 1.dp)
.background(Color.White)
.clickable {
Toast
.makeText(context, data, Toast.LENGTH_SHORT)
.show()
}
)
}
}
}
/**
* 基础列表一
*/
@Composable
fun Items() {
Box(modifier = Modifier.fillMaxSize()) {
val context = LocalContext.current
val dataList = arrayListOf()
for (index in 1..50) {
dataList.add(index)
}
val listState = rememberLazyListState()
LazyColumn(state = listState) {
items(dataList) { data ->
Text(
text = "第${data}条数据",
textAlign = TextAlign.Center,
//属性设置先后顺序不一样运行效果会不一样
modifier = Modifier
.fillMaxWidth()
.padding(top = 1.dp)
.background(Color.White)
.clickable {
Toast
.makeText(context, "$data", Toast.LENGTH_SHORT)
.show()
}
.padding(10.dp)
)
}
}
//返回顶部
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 = "返回顶部图标"
)
}
}
@Preview(showBackground = true, showSystemUi = true)
@Composable
fun GreetingPreview() {
ComposeDemoTheme {
Greeting()
}
}