【Android Compose】实现宜家 双联列表
双联列表
- 效果图
- 代码
- 解析
- 主要矛盾
- 性能问题:
- 次要矛盾
效果图
!
实现宜家 双联列表
00001.jpg?auth_key=4818491540-0-0-c8bbe27fc97f582aa0dd1b29a371a81f)(title-实现宜家 双联列表)]
代码
/*** 双联动列表* @param leftList List<String> 左侧条目* @param scrollToItem Function1<Int, Int> 右侧滑动影响左侧位置* @param itemToScroll Function1<Int, Int> 左侧滑动影响右侧位置,与上者互为反函数* @param content [@kotlin.ExtensionFunctionType] Function1<LazyListScope, Unit> 右侧内容填充物*/
@Composable
fun PartList(leftList : List<String>,scrollToItem : (Int) -> Int,itemToScroll : (Int) -> Int,content: LazyListScope.() -> Unit
)
{// 滑动状态val leftScrollState = rememberLazyListState()val rightScrollState = rememberLazyListState()// Remember a CoroutineScope to be able to launchval coroutineScope = rememberCoroutineScope()// 点击左侧的位置var onClickItem by remember {mutableStateOf(-1)}// 滑动右侧条目时,左侧联动// https://blog.csdn.net/vitaviva/article/details/121583183val getFirstVisibleItemIndex by remember {derivedStateOf {rightScrollState.firstVisibleItemIndex}}LaunchedEffect(Unit) {snapshotFlow { getFirstVisibleItemIndex }.collect {onClickItem = scrollToItem(it)}}// run {// 这里应该自行设计何处位置为标头
// onClickItem = scrollToItem(rightScrollState.firstVisibleItemIndex)// todo positive
// coroutineScope.launch {
// leftScrollState.scrollToItem(onClickItem)
// }
// }Row(modifier = Modifier.fillMaxSize()){LazyColumn(state = leftScrollState,modifier = Modifier.fillMaxHeight().background(IKEA_GRAY_LIGHT).weight(2f)){items(leftList.size){Row(modifier = Modifier.fillMaxWidth().height(40.dp).background(if (onClickItem == it) white else IKEA_GRAY_LIGHT) // val IKEA_GRAY_LIGHT = Color(245, 245, 245).clickable {// 点击左侧时设置跳转状态onClickItem = itcoroutineScope.launch {rightScrollState.animateScrollToItem(itemToScroll(it))}},verticalAlignment = Alignment.CenterVertically,horizontalArrangement = Arrangement.Center) {Text(text = leftList[it],modifier = Modifier,color = if(onClickItem == it) Color.Blue else Color.Black,fontSize = 11.sp,)}}}Spacer(modifier = Modifier.weight(0.5f))LazyColumn(state = rightScrollState,modifier = Modifier.fillMaxHeight().weight(8f),content = content)}
}
解析
主要矛盾
联动采用将两边滑动状态上提然后根据规则变动:
- 状态上提方法:
通过rememberLazyListState
来获取滑动状态
@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF)
@Composable
fun PartList()
{// 滑动状态val leftScrollState = rememberLazyListState()val rightScrollState = rememberLazyListState()Row {// 左侧LazyColumn(state = leftScrollState,。。。){。。。。}Spacer(modifier = Modifier.weight(0.5f))// 右侧LazyColumn(state = rightScrollState,。。。) {。。。。}}
}
- 点击 左侧,右侧滑动到相应位置:
a. 点击右侧:左侧跳转到相应标头
b. 滑动右侧到新的标头:左侧跟着跳转
a) 左侧只要监听点击事件,然后对右侧跳转即可:
我们以 左侧条目 的 Modifier
来进行点击事件监听:
.clickable {onClickItem = it // it 是思点击左侧的索引号// 点击左侧时设置跳转状态,这里跳转标头可以自己设定coroutineScope.launch {rightScrollState.animateScrollToItem(it * 3)}
}
b) 右侧滑动是实时监听的,所以只需要在函数内最上层写相关变化即可:
// 滑动右侧条目时,左侧联动run {// 这里应该自行设计何处位置为标头onClickItem = (rightScrollState.firstVisibleItemIndex / 3)coroutineScope.launch {leftScrollState.animateScrollToItem(onClickItem)}}
性能问题:
上文中,直接访问rememberLazyListState
的firstVisibleItemIndex 不是一个好选择,他会造成性能问题。
在使用 LazyColumn 或者 LazyRow 时,应该避免在 LazyListScope 中访问 LazyListState,这可能会造成隐藏的性能问题
因此,我们需要改进:将判断 list 滚动的逻辑抽象为一个 getFirstVisibleItemIndex
状态,然后通过 snapshotFlow
单独定义其变化,这样避免 LazyColumn
的 content
的重组。
val getFirstVisibleItemIndex by remember {derivedStateOf {rightScrollState.firstVisibleItemIndex}}LaunchedEffect(Unit) {snapshotFlow { getFirstVisibleItemIndex }.collect {onClickItem = scrollToItem(it)}}
次要矛盾
也就是尽可能符合宜家设计标准:
- 点击左侧,左侧跳转到指定位置,这里就引入
onClickItem
和其他外观区别。 - 其他讨论脱离文章范畴,不赘述。
【Android Compose】实现宜家 双联列表相关推荐
- Android JetPack Compose初步2~实现可滚动列表的功能
Android JetPack Compose的配置参考Android JetPack Compose初步1 在本应用中定义可滚动的列表的界面,类似RecyclerView组件的显示效果. 一.定义实 ...
- android自带下拉阻尼动画,android 有阻尼下拉刷新列表的实现方法
本文将会介绍有阻尼下拉刷新列表的实现,先来看看效果预览: 这是下拉状态: 这是下拉松开手指后listView回滚到刷新状态时的样子: 1. 如何调用 虽然效果图看起来样子不太好看,主要是因为那个蓝色的 ...
- Android Compose——一个简单的Bilibili APP
Bilibili移动端APP 简介 依赖 效果 登录 效果 WebView 自定义TobRow的Indicator大小 首页 推荐 LazyGridView使用Paging3 热门 排行榜 搜索 模糊 ...
- 用树莓派4B和宜家台灯玩转AR投影黑科技(神卓互联系列)
这是一款用树莓派(Raspberry Pi)和宜家台灯制作的智能家具,应用 Android Things 系统来实现 AR(增强现实)投影灯. Nord Projects 表示我们已经制作了一些类似的 ...
- 像宜家《家居指南》那样做邮件营销
在Econsultancy.com的一项市场调研中发现,有68 %的公司认可电子邮件渠道,尽管他们在邮件营销上的市场预算仅为16%.而61%的市场营销人员却对自己的邮件营销不满意.邮件营销才是onli ...
- android毕业设计——基于Android+XAMPP+MySQL的家校互动平台设计与实现(毕业论文+程序源码)——家校互动平台
基于Android+XAMPP+MySQL的家校互动平台设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于Android+XAMPP+MySQL的家校互动平台设计与实现,文章末尾附有本毕业设 ...
- Android SystemUI之Recent,近期列表(五)
Android SystemUI系列: 1.Android SystemUI之启动流程(一) 2.Android SystemUI之StatusBar,状态栏(二) 3.Android Syste ...
- 魔改宜家灯泡当主机,玩转《毁灭战士》无压力!网友:远超我家第一台电脑...
贾浩楠 胡子豪 发自 凹非寺 量子位 报道 | 公众号 QbitAI 这年头,"万物皆可<毁灭战士>"!(Doom) 极客们把这款猛男必玩的游戏移植到五花八门的设备上, ...
- 宜家如何利用低代码平台提升员工效率,提高数据价值
低代码开发已经在全球范围内的不同行业.不同企业中得到应用,并且使用的场景.角色等也在不断拓展.本文介绍低代码在零售领域的应用:构建敏捷的客户服务管理案例.此案例中不仅介绍了明确的人物角色和场景背景,还 ...
最新文章
- 腾讯发布人工智能辅助翻译,致敬人工翻译
- lnmp中怎么运行ngin和mysql_安装LNMP(Nginx+Mysql+PHP)
- Leetcode 67. 二进制求和 (每日一题 20210826)
- 持续5个月,200+笔记,3千多人参与,邀请你来学源码~
- leetcode 700. 二叉搜索树中的搜索 思考分析
- IBM Copy Service--Flashcopy Introduction
- 趣头条将获得阿里1.71亿美元的可转债,为期三年
- 布尔型Boolean+undefined+null(JS)
- Win10 环境变量配置
- imazing iOS设备管理软件
- 宁要城市一张床,不要农村一栋房
- ORA-22835:缓冲区对于CLOB到CHAR转换而言太小
- Microsoft visual studio关闭安全检查的几种方法
- NVIDIA详细解读游戏中DX9与DX11差别
- BugFree使用指南
- Daily Growing 的歌词
- 程序设计思想与方法 笔记
- 无桥PFC的优势及解决方案
- JS将秒数换算成时分秒 以及转化为年月日 时分秒以及多长时间以前
- 计算机网络实验以太网帧分析,实验二 用Ethereal捕获并分析以太网帧格式
热门文章
- 最新虚拟机SAP ECC6.0 EHP7带示例数据IDES版+BW740
- 贪心算法--最小耗费生成树(Prim算法)
- Html5 学习笔记 【PC固定布局】 实战5 咨询页面 侧栏
- 美团运维SRE+运维开发一面面经汇总
- 苹果电脑和手机浏览器的区分
- Gym - 101653T Runes [模拟]
- python import random 报错_导致python中import错误的原因是什么
- 分布式学习(3)etcd@2@HTTP API v2
- LiveGBS-摄像机网页低延时无插件直播实现
- vrchat模型保存_轻松简单自己上传VRChat的Avatar