Android Jetpack Compose——一个简单的聊天界面
创始人
2024-02-28 16:18:23
0

Jetpack Compose——聊天界面

  • 前言
  • 效果视频
  • 引入
    • Row
    • Column
    • Text
    • Image
  • 聊天界面
    • 效果
    • 左边布局
  • 右边布局
  • 插入数据
  • 总结

前言

目前声明式UI已经成为前端开发趋势,除了一开始的跨端开发React,Flutter等以及Web支持外,后续Android和IOS平台也相继推出声明式开发,Android通过Jetpack Compose配合Kotlin强大的语言特性进行开发,彻底摆脱啦命令式使用XML文件进行UI布局

效果视频

Android Jetpack ——一个简单的聊天界面

引入

在进行代码解析之前,先介绍几个常见的布局

Row

类似于Android中LinearLayout的horizontal排列方式,与Flutter的Row一致。
Modifier基本执行了一个组件大部分配置工作,内部实现了一些列扩展函数并通过then函数实现链式调用,verticalAlignment属性为竖向对齐方式,horizontalArrangement为横向对齐方式

Row(modifier = Modifier.padding(all = 10.dp),verticalAlignment = Alignment.CenterVertically,horizontalArrangement = Arrangement.Start)  {//some sub views}

Column

Column和Row除了排列方式不一样,其余都大致差不多,类似于LinearLayout的vertical排列方式

Column(modifier = Modifier.weight(1f),horizontalAlignment = Alignment.End){//some sub views}

Text

文本框,类似Android的TextViewtext属性为文本内容,color属性为文本颜色,style属性为文本样式,可以设置文本大小、是否加粗、样式等,系统内置了很多样式,textAlign属性为文本对齐方式

Text(text = msg.author,color = MaterialTheme.colorScheme.secondary,style = MaterialTheme.typography.bodySmall,textAlign = TextAlign.Right)

Image

等同于Android的ImageView,painter通过painterResource可以直接配置图片地址(drawable),通过modifier属性我们可以直接修改图片的是否圆角、边框、大小等属性,就不需要专门去建立一个xml文件去配置

Image(painter = painterResource(id = msg.img),contentDescription = "",modifier = Modifier.size(40.dp).clickable { CircleShape }.border(1.dp, MaterialTheme.colorScheme.secondary, CircleShape))

聊天界面

通过LazyColumn实现了一个竖向列表,数据为固定数据,根据下标分别位于左右俩端布局位置,然后默认文字显示一行,通过点击该行文字之后,文字内容进行展开,并改变其背景颜色,此Demo改编自官方

效果

左边布局

添加@Composable注解,才能使用声明式UI,声明式UI采用的都是树形结构,以此例,Row为该树根节点,拥有俩个子节点,分别为ImageColumn(中间那个空间占位符省略),然后Column又拥有俩个子节点,分别为SurfaceText,其中Surface又拥有一个Text子节点。

监听某行是否被点击,然后执行背景修改主要通过如下,就是相当于观察者模式,监听isExpanded字段,然后发生改变,就立即通过观察者类似。官方解释如下:

重组:可组合函数可以使用 remember 将本地状态存储在内存中,并跟踪传递给 mutableStateOf 的值的变化。
该值更新时,系统会自动重新绘制使用此状态的可组合项(及其子项)
通过使用 Compose 的状态 API(如 remember 和 mutableStateOf),系统会在状态发生任何变化时自动更新界面。
//监听isExpanded字段
var isExpanded by remember { mutableStateOf(false) }//收缩和扩展对应俩种颜色,由isExpanded字段决定val surfaceColor by animateColorAsState(targetValue = if (isExpanded)Color.CyanelseMaterialTheme.colorScheme.surface)

最后在需要添加点击方法的组件中添加 modifier = Modifier .clickable { isExpanded = !isExpanded }即可,每一次点击都改变其值,然后获取该值的节点进行重绘,更新

@Composable
fun MessageLeft(msg : Message){Row(modifier = Modifier.padding(all = 10.dp),verticalAlignment = Alignment.CenterVertically,horizontalArrangement = Arrangement.Start) {//图像Image(painter = painterResource(id = msg.img),contentDescription = "",modifier = Modifier.size(40.dp)//图像大小.clip(CircleShape).border(1.dp, MaterialTheme.colorScheme.secondary, CircleShape))//左右间隔Spacer(modifier = Modifier.width(10.dp))//重组:可组合函数可以使用 remember 将本地状态存储在内存中,并跟踪传递给 mutableStateOf 的值的变化。// 该值更新时,系统会自动重新绘制使用此状态的可组合项(及其子项)//通过使用 Compose 的状态 API(如 remember 和 mutableStateOf),系统会在状态发生任何变化时自动更新界面。var isExpanded by remember { mutableStateOf(false) }val surfaceColor by animateColorAsState(targetValue = if (isExpanded)Color.CyanelseMaterialTheme.colorScheme.surface)Column() {Text(text = msg.author,color = MaterialTheme.colorScheme.secondary,style = MaterialTheme.typography.bodySmall)//上下间隔Spacer(modifier = Modifier.height(10.dp))Surface(shape = RectangleShape,shadowElevation = 1.dp,tonalElevation = 1.dp,color = surfaceColor,modifier = Modifier.animateContentSize().padding(1.dp)) {Text(text = msg.content,modifier = Modifier.clickable { isExpanded = !isExpanded }.padding(all = 4.dp),maxLines = if (isExpanded) Int.MAX_VALUE else 1,style = MaterialTheme.typography.bodyMedium,overflow = TextOverflow.Ellipsis)}}}
}

右边布局

右边与左边差不多,不同点在于改变了horizontalArrangement排列方式,使其呈右边排列,然后给文字添加了一个权重属性 modifier = Modifier.weight(1f),,防止该行内容过多,将右边图像挤到屏幕之外

@Composable
fun MessageRight(msg: Message){Row(modifier = Modifier.padding(10.dp).fillMaxWidth(),verticalAlignment = Alignment.CenterVertically,horizontalArrangement = Arrangement.End) {//给左边文字一个权重,避免文字过多,让右边图像无法显示Column(modifier = Modifier.weight(1f),horizontalAlignment = Alignment.End) {Text(text = msg.author,color = MaterialTheme.colorScheme.secondary,style = MaterialTheme.typography.bodySmall,textAlign = TextAlign.Right)Spacer(modifier = Modifier.height(10.dp))var isExpanded by remember { mutableStateOf(false) }val surfaceColor by animateColorAsState(targetValue = if (isExpanded)Color.GreenelseMaterialTheme.colorScheme.surface)Surface(shape = RectangleShape,shadowElevation = 1.dp,tonalElevation = 1.dp,color = surfaceColor,modifier = Modifier.animateContentSize().padding(1.dp)) {Text(text = msg.content,modifier = Modifier.clickable { isExpanded = !isExpanded }.padding(all = 4.dp),maxLines = if (isExpanded) Int.MAX_VALUE else 1,style = MaterialTheme.typography.bodyMedium,overflow = TextOverflow.Ellipsis)}}Spacer(modifier = Modifier.width(10.dp))Image(painter = painterResource(id = msg.img),contentDescription = "",modifier = Modifier.size(40.dp).clickable { CircleShape }.border(1.dp, MaterialTheme.colorScheme.secondary, CircleShape))}
}

插入数据

等同于Android XML的RecyclerView,是不是很简单,不需要写Adapter和子项XMl文件以及一大堆接口什么的啦

@Composable
fun ShowMessage(msgList: List){//竖向列表LazyColumn{itemsIndexed(items = msgList){index, item ->if (index %2 == 0)MessageLeft(msg = item)elseMessageRight(msg = item)}}
}

总结

Jetpack Compose 声明式UI一开始用起来可能不太习惯,但是适应之后,直接起飞,大大提高开发效率,减少开发时间,而且大部分前端都使用声明式UI,想要兼修,就不必费很大功夫,就例如Flutter,从UI而言俩个基本都差不多,只不过Flutter通过Widget进行嵌套,分为WidgetElementRenderObject三个部分,通过runtimetypekey判断此节点是否修改,从而判断是否需要进行重绘。
最后建议诸位Android开发者用起来,Android Jetpack Compose已经差不多出来有一年时间啦,逐渐稳定

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...