【开源项目】Compose仿豆瓣榜单客户端,了解一下~
作者:RicardoMJiang
原文地址:https://juejin.cn/post/6999775929228591112
前言
Compose正式发布也有一段时间了,感觉要上手还是得实战一波。
所以借着空闲时间,参照豆瓣榜单页面的设计,开发了几个Compose版的豆瓣榜单页面UI效果还是挺好看的,有兴趣的同学可以点个Star:Compose仿豆瓣榜单客户端
效果图
首先看下最终的效果图
特性
在项目中主要用到了以下几个特性,以美化UI及体验
支持设置沉浸式状态栏及状态栏颜色
支持水平方向滚动,竖直方向滚动等多种
UI效果支持给
Image设置渐变滤镜,以美化显示效果支持标题与列表页联动
通过
Paging支持了分页加载
主要实现
具体源码可以直接查看,这里主要介绍一些主要功能的实现
沉浸式状态栏设置
状态栏主要是通过accompanist-insets及accompanist-systemuicontroller库设置的
accompanist上提供了一系列常用的,如状态栏,权限,FlowLayout,ViewPager等Compose库
如果有时你发现基础库里没有相应的内容,可以去这里查找下
设置状态栏主要分为以下几步
设置沉浸时状态栏
获取状态栏高度
设置状态栏颜色
1override fun onCreate(savedInstanceState: Bundle?) {
2 super.onCreate(savedInstanceState)
3 // 1. 设置状态栏沉浸式
4 WindowCompat.setDecorFitsSystemWindows(window, false)
5
6 setContent {
7 BD_ToolTheme {
8 // 加入ProvideWindowInsets
9 ProvideWindowInsets {
10 // 2. 设置状态栏颜色
11 rememberSystemUiController().setStatusBarColor(
12 Color.Transparent, darkIcons = MaterialTheme.colors.isLight)
13 Column {
14 // 3. 获取状态栏高度并设置占位
15 Spacer(modifier = Modifier
16 .statusBarsHeight()
17 .fillMaxWidth())
18 Text(text = "首页\r\n首页1\r\n首页2\r\n首页3")
19 }
20 }
21 }
22 }
23 }
24复制代码
通过以上方法,就可以比较简单的实现沉浸状态栏的设置
`Image`设置渐变滤镜
豆瓣榜单页面都给Image设置了渐变滤镜,以美化UI效果
其实实现起来也比较简单,给Image前添加一层渐变的蒙层即可
1@Composable
2fun TopRankItem(item: HomeTopRank) {
3 Box(
4 modifier = Modifier
5 .size(180.dp, 220.dp)
6 .padding(8.dp)
7 .clip(RoundedCornerShape(10.dp))
8 ) {
9 // 1. 图片
10 Image(
11 painter = rememberCoilPainter(request = item.imgUrl),
12 contentDescription = null,
13 contentScale = ContentScale.Crop,
14 modifier = Modifier.fillMaxSize()
15 )
16 Column(
17 modifier = Modifier
18 .fillMaxSize()
19 // 渐变滤镜
20 .background(
21 brush = Brush.linearGradient(
22 colors = listOf(Color(item.startColor), Color(item.endColor)),
23 start = Offset(0f, Float.POSITIVE_INFINITY),
24 end = Offset(Float.POSITIVE_INFINITY, 0f)
25 )
26 )
27 .padding(8.dp)
28
29 ) {
30 //内容
31 }
32 }
33}
34复制代码
如上所示,使用Box布局,给前景设置一个从左下到右上渐变的背景即可
标题与列表联动
具体效果可见上面的动图,即在列表滚动时标题会有一个渐现渐隐效果
这个效果其实我们在Android View体系中也很常见,主要思路也很简单:
监听列表滚动,获取列表滚动
offset根据列表滚动
offset设置Header效果,如背景或者高度变化等
1@Composable
2fun RankScreen(viewModel: RankViewModel = RankViewModel()) {
3 val scrollState = rememberLazyListState()
4 Box {
5 // 1. 监听列表
6 LazyColumn(state = scrollState) {
7 //列表内容
8 }
9 RankHeader(scrollState)
10 }
11}
12
13@Composable
14fun RankHeader(scrollState: LazyListState) {
15 val target = LocalDensity.current.run {
16 200.dp.toPx()
17 }
18 // 2. 根据列表偏移量计算比例
19 val scrollPercent: Float = if (scrollState.firstVisibleItemIndex > 0) {
20 1f
21 } else {
22 scrollState.firstVisibleItemScrollOffset / target
23 }
24 val activity = LocalContext.current as Activity
25 val backgroundColor = Color(0xFF7F6351)
26 Column() {
27 Spacer(
28 modifier = Modifier
29 .fillMaxWidth()
30 .statusBarsHeight()
31 // 3. 根据比例设置Header的alpha,以实现渐变效果
32 .alpha(scrollPercent)
33 .background(backgroundColor)
34 )
35 //....
36 }
37}
38复制代码
如上所示,主要有三步:
监听列表
根据列表偏移量计算比例
根据比例设置
Header的alpha,以实现渐变效果
利用`Paging`实现分页
目前Pagin3已经支持了Compose,我们可以利用Paging轻松实现分页效果
主要分为以下几步:
在
ViewModel中设置数据源在页面中监听
Paging数据根据加载状态设置加载更多
footr状态
1//1. 设置数据源
2class RankViewModel : ViewModel() {
3 val rankItems: Flow<PagingData<RankDetail>> =
4 Pager(PagingConfig(pageSize = 10, prefetchDistance = 1)) {
5 MovieSource()
6 }.flow
7}
8
9@Composable
10fun RankScreen(viewModel: RankViewModel = RankViewModel()) {
11 val lazyMovieItems = viewModel.rankItems.collectAsLazyPagingItems()
12 Box {
13 LazyColumn(state = scrollState) {
14 // 2. 在页面中监听paging
15 items(lazyMovieItems) {
16 it?.let {
17 RankListItem(it)
18 }
19 }
20 // 3. 根据paging状态设置加载更多footer状态等
21 lazyMovieItems.apply {
22 when (loadState.append) {
23 is LoadState.Loading -> {
24 item { LoadingItem() }
25 }
26 }
27 }
28 }
29 }
30}
31复制代码
通过以上步骤,就可以比较简单方便地实现分页了
总结
项目地址
ComposeDouban
开源不易,如果项目对你有所帮助,欢迎点赞,Star,收藏~
参考资料
Android Jetpack Compose 沉浸式/透明状态栏
Collapsing Toolbar made easy with Compose
Infinite Lists With Paging 3 in Jetpack Compose
推荐阅读
android ViewPager 仿画廊/图书翻页 与 palette 使用
耗时一周,我解决了微信 Matrix 增量编译的 Bug,已提 PR
Android QMUI实战:实现APP换肤功能,并自动适配手机深色模式
公众号徐公回复黑马,获取 Android 学习视频 公众号徐公回复徐公666,获取简历模板,教你如何优化简历,走近大厂 公众号徐公回复面试,可以获得面试常见算法,剑指 ofer 题解 公众号徐公回复马士兵,可以获得马士兵学习视频一份