Jetpack Compose 列表吸顶效果实现

1,230 阅读2分钟

这篇文章主要介绍“Android Jetpack Compose如何实现列表吸顶效果”,整理出了简单好用的操作方法,希望对大家有所帮助!

列表和网格

Compose 提供了一组组件,这些组件只会对在组件视口中可见的列表项进行组合和布局。这些组件包括LazyColumnLazyRow。 从名称可以看出,LazyColumnLazyRow之间的区别就在于它们的列表项布局和滚动方向不同。LazyColumn生成的是垂直滚动列表,而LazyRow生成的是水平滚动列表。

stickyHeader

Compose设计的时候考虑得很周到,他们提供了stickyHeader

作用就是添加一个粘性标题项,即使在它后面滚动时也会保持固定。标头将保持固定,直到下一个标头取而代之。

实体类

创建一个实体类标题和内容

data class Bean(
    val title: String,
    val contentData: List<String>
)

增加显示数据

val list: MutableList<Bean> = mutableListOf()
for (index in 1..20) {
    val contentData: MutableList<String> = mutableListOf()
    for (i in 1..5) {
        contentData.add("HelloAndroid $i")
    }
    list.add(Bean("标题$index", contentData))
}

定义一个垂直滚动列表,仅构成和布局当前可见的项目

LazyColumn(
    modifier = Modifier
        .fillMaxWidth()
        .fillMaxHeight(),
    contentPadding = PaddingValues(vertical = 10.dp)
) {
    list.forEachIndexed { position, post ->
        stickyHeader {
            ListTitle(title = post.title) {
                //点击事件
            }
        }
        item {
            StructureItem(post.contentData)
            Spacer(modifier = Modifier.height(10.dp))
        }
    }
}

吸顶标题

接着封装一个吸顶标题,并传出点击事件

@Composable
fun ListTitle(
    modifier: Modifier = Modifier,
    title: String,
    onSubtitleClick: () -> Unit = {}
) {
    Row(
        modifier = modifier
            .fillMaxWidth()
            .height(30.dp)
            .background(color = Color.Gray),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Text(
            modifier = Modifier
                .padding(horizontal = 10.dp)
                .width(5.dp)
                .height(16.dp)
                .background(color = Color.Black),
            text = "",
            color = Color.Black,
        )
        Text(text = title, color = Color.White)
    }

}

效果

image.png

二级视图

Row是以水平方向进行布局的,非常类似于 LinearLayout 设置水平排列的布局方式。

@Composable
fun ListTitle(
    modifier: Modifier = Modifier,
    title: String,
    onSubtitleClick: () -> Unit = {}
) {
    Row(
        modifier = modifier
            .fillMaxWidth()
            .height(30.dp)
            .background(color = Color.Gray),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Text(
            modifier = Modifier
                .padding(horizontal = 10.dp)
                .width(5.dp)
                .height(16.dp)
                .background(color = Color.Black),
            text = "",
            color = Color.Black,
        )
        Text(text = title, color = Color.White)
    }

}

效果

image.png

附上完整代码

@Preview
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun StickyHeaderScreen() {
    val list: MutableList<Bean> = mutableListOf()
    for (index in 1..20) {
        val contentData: MutableList<String> = mutableListOf()
        for (i in 1..5) {
            contentData.add("HelloAndroid $i")
        }
        list.add(Bean("标题$index", contentData))
    }
    LazyColumn(
        modifier = Modifier
            .fillMaxWidth()
            .fillMaxHeight(),
        contentPadding = PaddingValues(vertical = 10.dp)
    ) {
        list.forEachIndexed { position, post ->
            stickyHeader {
                ListTitle(title = post.title) {
                    //点击事件
                }
            }
            item {
                StructureItem(post.contentData)
                Spacer(modifier = Modifier.height(10.dp))
            }
        }
    }
}

data class Bean(
    val title: String,
    val contentData: List<String>
)

@Composable
fun ListTitle(
    modifier: Modifier = Modifier,
    title: String,
    onSubtitleClick: () -> Unit = {}
) {
    Row(
        modifier = modifier
            .fillMaxWidth()
            .height(30.dp)
            .background(color = Color.Gray),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Text(
            modifier = Modifier
                .padding(horizontal = 10.dp)
                .width(5.dp)
                .height(16.dp)
                .background(color = Color.Black),
            text = "",
            color = Color.Black,
        )
        Text(text = title, color = Color.White)
    }

}

@Composable
fun StructureItem(
    bean: List<String>
) {
    Row(modifier = Modifier.padding(horizontal = 6.dp)) {
        for (item in bean) {
            Box(modifier = Modifier.padding(horizontal = 2.dp, vertical = 3.dp)) {
                TextButton(
                    modifier = Modifier
                        .padding(horizontal = 3.dp)
                        .height(34.dp),
                    shape = RoundedCornerShape(12.dp),
                    onClick = { },
                    colors = ButtonDefaults.textButtonColors(
                        containerColor = Color.Red
                    )
                ) {
                    Text(text = item, color = Color.White)
                }
            }
        }
    }
}

运行效果图

image.png

总结

到此这篇关于Android Jetpack Compose实现列表吸顶效果的文章就介绍到这了。