文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android Compose如何实现联系人列表

2023-07-05 11:19

关注

这篇文章主要介绍“Android Compose如何实现联系人列表”,在日常操作中,相信很多人在Android Compose如何实现联系人列表问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Android Compose如何实现联系人列表”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

效果:

Android Compose如何实现联系人列表

准备数据

data class ContactEntity(    val letter: Char,    val name: String,    val color: Color)fun getContactData(): MutableList<ContactEntity> {    val contactList = mutableListOf<ContactEntity>()    (65..90).forEach { letter ->//        val random = (5..20).random()        val random = 5        repeat(random) { index ->            contactList.add(                ContactEntity(                    letter = letter.toChar(), name = "联系人  $index",                    color = Color(                        red = (0..255).random(),                        blue = (0..255).random(),                        green = (0..255).random()                    )                )            )        }    }    return contactList}fun getCharList(): MutableList<Char> {    val charList = mutableListOf<Char>()    (65..90).forEach { letter ->        charList.add(letter.toChar())    }    return charList}

思路

代码实现

@OptIn(ExperimentalTextApi::class)@Composablefun ContactPage(navCtrl: NavHostController, title: String) {    //联系人数据    val contactList = getContactData()    //字母数据    val charList = getCharList()    val offsetY = with(LocalDensity.current) {        20.dp.toPx()    }    val offsetX = with(LocalDensity.current) {        25.dp.toPx()    }    val coroutineScope = rememberCoroutineScope()    val textMeasure = rememberTextMeasurer()    val state = rememberLazyListState()    //触摸的位置    var touchOffset by remember() {        mutableStateOf(Offset.Zero)    }    //触摸到的上一次的字母下标    var touchIndexLast by remember {        mutableStateOf(-1)    }    //触摸的字母的下标    val touchIndex = remember(touchOffset.y) {        derivedStateOf {            if (touchOffset.y > 0f) {                //通过偏移的倍数计算滑动到哪个字母的位置了                val y = (touchOffset.y / offsetY).roundToInt()                if (y in 0..25) {                    touchIndexLast = y                    y                } else {                    touchIndexLast                }            } else touchIndexLast        }    }    //触摸到的字符的index    val touchLetterIndex = remember {        derivedStateOf {            if (state.isScrollInProgress && state.layoutInfo.visibleItemsInfo.isNotEmpty()) {                val key = state.layoutInfo.visibleItemsInfo[0].key                if (key is Int && key < contactList.size) {                    val letter = contactList[key].letter                    val findIndex = charList.indexOfFirst {                        it == letter                    }                    findIndex                } else {                    touchIndex.value                }            } else {                touchIndex.value            }        }    }    //上一次选择的letter    var lastLetter by remember {        mutableStateOf("")    }    //滑动到的letter    val scrollLetter = remember {        derivedStateOf {            if (touchIndex.value > 0) {                val letter = (65 + touchIndex.value).toChar()                coroutineScope.launch {                    //找到相应的item                    val index = getIndex(contactList, letter)                    state.scrollToItem(index, scrollOffset = 20)                }                val str = letter.toString()                lastLetter = str                str            } else {                lastLetter            }        }    }    CommonToolbar(navCtrl, title) {        Box(modifier = Modifier.fillMaxSize()) {            LazyColumn(modifier = Modifier.fillMaxWidth(), state = state, content = {                contactList.forEachIndexed { index, contactEntity ->                    item(key = index) {                        Column(                            modifier = Modifier.fillMaxWidth()                        ) {                            Row(                                modifier = Modifier                                    .fillMaxWidth()                                    .padding(horizontal = 10.dp),                                verticalAlignment = Alignment.CenterVertically                            ) {                                Box(                                    modifier = Modifier                                        .size(50.dp)                                        .clip(CircleShape)                                        .background(                                            color = contactEntity.color,                                        ), contentAlignment = Alignment.Center                                ) {                                    Text(                                        text = "${contactEntity.letter}",                                        fontSize = 16.sp,                                        color = Color.White,                                        fontWeight = FontWeight.SemiBold,                                    )                                }                                Text(                                    text = contactEntity.name,                                    modifier = Modifier                                        .padding(20.dp)                                        .weight(1f)                                        .padding(horizontal = 10.dp, vertical = 16.dp)                                )                            }                            Divider()                        }                    }                }                item {                    Text(                        text = "共${contactList.size}联系人",                        fontSize = 12.sp,                        color = Color(0xFF333333),                        modifier = Modifier                            .fillMaxWidth()                            .padding(vertical = 20.dp),                        textAlign = TextAlign.Center                    )                }            })            //绘制右侧的26个字母            Canvas(modifier = Modifier                .padding(top = 30.dp)                .width(50.dp)                .fillMaxHeight()                .align(Alignment.TopEnd)                .pointerInput(Unit) {                    coroutineScope {                        while (true) {                            // down事件                            val downPointerInputChange = awaitPointerEventScope {                                awaitFirstDown()                            }                            // 如果位置不在手指按下的位置,先动画的形式过度到手指按下的位置                            if (touchOffset.x != downPointerInputChange.position.x && touchOffset.y != downPointerInputChange.position.y) {                                launch {                                    touchOffset = downPointerInputChange.position                                }                            }                            // touch Move事件                            // 滑动的时候,box随着手指的移动去移动                            awaitPointerEventScope {                                drag(downPointerInputChange.id, onDrag = {                                    touchOffset = it.position                                })                            }                            // 在手指弹起的时候,才通过动画的形式,回到原点的位置                            val dragUpOrCancelPointerInputChange = awaitPointerEventScope {                                awaitDragOrCancellation(downPointerInputChange.id)                            }                            // 等于空,说明已经抬起                            if (dragUpOrCancelPointerInputChange == null) {                                launch {                                    touchOffset = Offset.Zero                                }                            }                        }                    }                }, onDraw = {                charList.forEachIndexed { index, char ->                    drawText(                        size = Size(width = offsetY, offsetY),                        textMeasurer = textMeasure, text = "$char",                        style = TextStyle(                            fontWeight = if (touchLetterIndex.value == index) FontWeight.SemiBold else FontWeight.Medium,                            color = if (touchLetterIndex.value == index) Color.Blue else Color(                                0xFF333333                            ),                            textAlign = TextAlign.Center,                            fontSize = if (touchLetterIndex.value == index) 16.sp else 14.sp                        ),                        topLeft = Offset(offsetX, offsetY * index),                    )                }            })            //中间显示的大写字母            val textMeasurer1 = rememberTextMeasurer()            if (touchOffset.x != 0f && touchOffset.y != 0f && scrollLetter.value.isNotEmpty()) {                val annotatedString = AnnotatedString(                    scrollLetter.value, spanStyle = SpanStyle(                        fontWeight = FontWeight.Medium,                        color = Color(0xFF333333),                        fontSize = 20.sp,                    )                )                val textLayoutResult = textMeasurer1.measure(text = annotatedString)                val textSize = textLayoutResult.size                Canvas(modifier = Modifier                    .align(Alignment.Center)                    .requiredSize(width = 50.dp, height = 50.dp), onDraw = {                    //底部颜色                    drawRoundRect(                        color = Color(0xA403A9F4), cornerRadius = CornerRadius(10f, 10f)                    )                    //绘制字母                    drawText(                        textMeasurer = textMeasurer1,                        text = annotatedString,                        topLeft = Offset(                            (size.width - textSize.width) / 2f,                            (size.height - textSize.height) / 2f                        )                    )                })            }        }    }}
private fun getIndex(list: MutableList<ContactEntity>, letter: Char): Int {    val findIndex = list.indexOfFirst { contactEntity ->        contactEntity.letter == letter    }    return findIndex}

到此,关于“Android Compose如何实现联系人列表”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯