返回顶部
首页 > 资讯 > 精选 >Android Compose如何实现联系人列表
  • 352
分享到

Android Compose如何实现联系人列表

2023-07-05 11:07:44 352人浏览 八月长安
摘要

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

这篇文章主要介绍“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}

思路

  • 整体是由Box布局包裹, 左侧是LazyColumn 右侧放置自定义布局

  • 左侧LazyColumn用state来观察滑动的一些参数,来控制右侧字母的位置

  • 右侧使用canvas绘制字母 在触控的时候使用scrollToItem准确的定位到左侧应该滑动的位置,感觉有些不准确,不知道是计算的问题还是bug,在谷歌上看到类似的issue提交。

  • 中间显示滑动到的字母,也可以使用贝塞尔曲线来绘制类似于水滴的样式,懒得去搞了。

  • 利用derivedStateOf来跟踪变化的remember数据,这样可以减少性能的损耗,但是感觉有个地方没处理好,就是触摸的时候需要改变,滑动的时候也需要改变,而derivedStateOf是val类型的,不能直接赋值,所以又设置了一个remember变量。有可以优化的地方请指出。

  • 数据和样式都可以自定义,非常方便

代码实现

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

--结束END--

本文标题: Android Compose如何实现联系人列表

本文链接: https://lsjlt.com/news/351304.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Android Compose如何实现联系人列表
    这篇文章主要介绍“Android Compose如何实现联系人列表”,在日常操作中,相信很多人在Android Compose如何实现联系人列表问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答...
    99+
    2023-07-05
  • iOS实现联系人列表功能
    本文实例为大家分享了iOS实现联系人列表功能的具体代码,供大家参考,具体内容如下 按照顺序排列联系人列表,需要引入一些工具(详见demo): 主要部分代码: #import "...
    99+
    2022-05-24
    iOS 联系人 列表
  • AndroidCompose实现联系人列表流程
    目录准备数据思路代码实现 准备数据 data class ContactEntity( val letter: Char, val name: String, ...
    99+
    2023-03-10
    Android Compose Android Compose实现联系人
  • Android实现可浏览和搜索的联系人列表
    通过这篇文章,我想说明一下如何创建一个可搜索的“联系人列表”Android应用程序。使用这个应用程序,用户可以通过使用导航按钮浏览所有保存的联系人和根据联系人名称搜索联系人。该...
    99+
    2022-06-06
    列表 联系 Android
  • Android Jetpack Compose如何实现列表吸顶效果
    这篇文章主要介绍“Android Jetpack Compose如何实现列表吸顶效果”,在日常操作中,相信很多人在Android Jetpack Compose如何实现列表吸顶效果问题上存在疑惑,小编...
    99+
    2023-06-29
  • android仿微信联系人索引列表功能
    前言  因为自己在做的一个小软件里面需要用到从A-Z排序的ListView,所以自然而然的想到了微信的联系人,我想要的就是那样的效果。本来没打算自己去写,想要第三方写好的东西,搜了几个之后发现有的太复杂了,有的简单是...
    99+
    2023-05-30
  • Android仿微信联系人列表字母侧滑控件
    仿微信联系人列表字母侧滑控件, 侧滑控件参考了以下博客:Android实现ListView的A-Z字母排序和过滤搜索功能首先分析一下字母侧滑控件应该如何实现,根据侧滑控件的高度和字母的数量来平均计算每个字母应该占据的高度。在View的onD...
    99+
    2023-05-31
    android 侧滑控件
  • android开发教程之使用listview显示qq联系人列表
    首先还是xml布局文件,在其中添加ListView控件: 主布局layout_main.xml 代码如下:<RelativeLayout xmlns:android="...
    99+
    2022-06-06
    程之 列表 listview android开发 教程 Android
  • android 加载本地联系人实现方法
    首先先建布局文件,界面很简单,就是一个搜索框和下面的联系人列表:   代码如下: <xml version="1.0" encoding="utf-8">...
    99+
    2022-06-06
    联系 方法 Android
  • Android实现手机联系人分栏效果
    本文实例为大家分享了Android实现手机联系人分栏效果的具体代码,供大家参考,具体内容如下 小编在项目时期遇见了制作手机联系人分栏效果,查询了很多资料,现在总结如下: 添加的代码并...
    99+
    2024-04-02
  • android实现读取、搜索联系人的代码
    代码很简单,就不多废话了 代码如下: //读取联系人 public static Uri CONTACTSURI = ContactsContract.Contacts.CO...
    99+
    2022-06-06
    搜索联系人 联系 Android
  • Android ContentProvider实现获取手机联系人功能
    在之前项目中有用到关于获取手机联系人的部分,闲置就想和大家分享一下,话不多说,上代码:java部分:package com.example.content; import android.content.ContentResolver; ...
    99+
    2023-05-30
    android contentprovider 联系人
  • Android Compose Column列表不自动刷新问题如何解决
    本篇内容介绍了“Android Compose Column列表不自动刷新问题如何解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能...
    99+
    2023-07-05
  • Android实现获取联系人电话号码功能
    本篇文档主要记录一下获取联系人的电话号码的一种方式。 1、选择联系人 ............ //构造一个隐式的Intent,拉起联系人界面 final Intent pi...
    99+
    2022-06-06
    电话 联系 Android
  • Android实现新增及编辑联系人的方法
    本文实例介绍了Android开发中对联系人修改、新增联系人的方法,通过本实例代码可实现添加联系人、编辑修改联系人,新增联系人和更新联系人等操作,操作主要放在线程中处理,并且在操...
    99+
    2022-06-06
    联系 方法 Android
  • Android怎么实现手机联系人分栏效果
    今天小编给大家分享一下Android怎么实现手机联系人分栏效果的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。效果图:adap...
    99+
    2023-06-29
  • Java实现联系人管理系统
    基于Java的联系人管理系统,供大家参考,具体内容如下 基于eclipse做的一个简单的联系人管理系统 对于联系人姓名首字母进行了一个排序,对于存入信息时手机号码与电子邮箱做了一个判...
    99+
    2024-04-02
  • Android中是如何获取手机联系人的
    这篇文章给大家介绍Android中是如何获取手机联系人的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Android 获取系统联系人信息的实例一、获取手机联系人姓名及手机号//跳转到系统联系人应用 Inten...
    99+
    2023-05-30
    android
  • 如何在Android应用中利用Intent实现获取联系人的信息
    今天就跟大家聊聊有关如何在Android应用中利用Intent实现获取联系人的信息,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Intent的使用intent是一个好东西他可以启动A...
    99+
    2023-05-31
    android intent
  • Android ContentProvider获取手机联系人实例
    在做项目的时候,因为要用到我们自动获取联系人的姓名和电话,就想到了ContentProvider分享数据的功能,这样做既节省了时间,也减少了我们输入错误号码的几率,所以,想在这...
    99+
    2022-06-06
    联系 手机 Android
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作