Android Studio compose的简单使用与案例实现
创始人
2024-03-22 06:28:01
0

Compose是Android团队与JetBrain大力推动的新一代UI框架,它能够简化安卓界面的开发,让本来繁琐的xml文件写法变为简便的kt文件写法。

其声明式 UI、更简单的自定义、实时且带交互的预览功能更是让安卓开发锦上添花

android compose框架的使用

  • 一.前置知识:Jetpack
    • 1.什么是Jetpack?
    • 2.为什么要使用Jetpack
    • 3.常用的Jetpack库
  • 二.正片:Compose入门
    • 1.Compose的编程思想
      • 简单的可组合函数
    • 2.创建一个Compose项目
  • 三.使用Compose完成“跑马灯”案例
    • 1.构建项目
    • 2.在主包下创建一个新的kt文件
    • 3.构建MarqueeText方法
      • 引用Compose中定义的ui参数
      • 创建控件方法
      • 对动态效果进行编码
      • 调用上述的方法
      • 实现启动类
      • 在xml启动文件中,添加这个kt文件
      • 实现效果
  • 4.总结

一.前置知识:Jetpack

1.什么是Jetpack?

Jetpack并不是一个框架或者组件,它是一套库、工具和指南的集合,可帮助开发者更轻松地编写优质应用。这些组件可帮助开发者遵循最佳做法、摆脱编写样板代码的工作并简化复杂任务,以便将精力集中放在所需的代码上。

2.为什么要使用Jetpack

1.替换以前的support库,提供一个更好,更加独立和稳健的兼容方案
2.官方实现了很多日常软件开发中需要用到的组件,消除重复样板代码
3.提高软件品质,核心库帮你绑定数据,管理生命周期和内容,让你专注在对自身业务重要的部分

3.常用的Jetpack库

图片取自安卓开发文档

二.正片:Compose入门

1.Compose的编程思想

Compose 是一个声明性界面框架。在过去的几年中,整个行业已开始转向声明性界面模型,该模型大大简化了与构建和更新界面关联的工程任务。该技术的工作原理是在概念上从头开始重新生成整个屏幕,然后仅执行必要的更改。此方法可避免手动更新有状态视图层次结构的复杂性。

简单的可组合函数

使用 Compose,可以通过定义一组接受数据而发出界面元素的可组合函数来构建界面。一个简单的示例是 Greeting widget,它接受 String 并发出一个显示问候消息的 Text widget。
简单的案例此函数带有 @Composable 注释。所有可组合函数都必须带有此注释;此注释可告知 Compose 编译器:此函数旨在将数据转换为界面。(类似于Spring框架的@Component

此函数接受数据。可组合函数可以接受一些参数,这些参数可让应用逻辑描述界面。在本例中,我们的 widget 接受一个 String,因此它可以按名称问候用户。

此函数可以在界面中显示文本。为此,它会调用 Text() 可组合函数,该函数实际上会创建文本界面元素。可组合函数通过调用其他可组合函数来发出界面层次结构。

此函数不会返回任何内容。发出界面的 Compose 函数不需要返回任何内容,因为它们描述所需的屏幕状态,而不是构造界面 widget。

2.创建一个Compose项目

1.如果您位于 Welcome to Android Studio 窗口中,请点击 Start a new Android Studio project。如果您已打开 Android Studio 项目,请从菜单栏中依次选择 File > New > New Project。

在这里插入图片描述
2.在 Select a Project Template 窗口中,选择 Empty Compose Activity,然后点击 Next。
在这里插入图片描述3.在 Configure your project 窗口中,执行以下操作:

按照常规方法设置 Name、Package name 和 Save location。请注意,在 Language 下拉菜单中,Kotlin 是唯一可用的选项,因为 Jetpack Compose 仅适用于使用 Kotlin 编写的类。
在 Minimum API level dropdown 菜单中,*选择 API 级别 21 或更高级别*。

在这里插入图片描述4.点击finish。

三.使用Compose完成“跑马灯”案例

1.构建项目

这一部分参照上文;

2.在主包下创建一个新的kt文件

我这里命名为“test”
在这里插入图片描述

3.构建MarqueeText方法

这是跑马灯实现的主要部分,在此部分来编辑跑马灯效果的静态参数与动态效果

引用Compose中定义的ui参数

在这里插入图片描述说明:

循环滚动跑马灯Text控件

  • text 文字内容
  • modifier 控件修饰器
  • textModifier 文字修饰器
  • gradientEdgeColor 左右边界渐变透明色,默认白色渐变。
  • color 文字颜色
  • letterSpacing 字符间距
  • textDecoration 文字装饰

创建控件方法

创建Text控件方法,相当于 @Composable fun createText(localModifier: Modifier)

在这里插入图片描述

对动态效果进行编码

var offset by remember { mutableStateOf(0) }val textLayoutInfoState = remember { mutableStateOf(null) }LaunchedEffect(textLayoutInfoState.value) {val textLayoutInfo = textLayoutInfoState.value ?: return@LaunchedEffectif (textLayoutInfo.textWidth <= textLayoutInfo.containerWidth) return@LaunchedEffectif(textLayoutInfo.containerWidth == 0) return@LaunchedEffect// 计算播放一遍的总时间val duration = 7500 * textLayoutInfo.textWidth / textLayoutInfo.containerWidth// 父层不要有其他元素,不然这句很容易发生Error java.lang.ArithmeticException: divide by zero(除以零)// 动画间隔时间val delay = 1000Ldo {// 定义动画,文字偏移量从0到-文本宽度val animation = TargetBasedAnimation(animationSpec = infiniteRepeatable(animation = tween(durationMillis = duration,delayMillis = 1000,easing = LinearEasing,),repeatMode = RepeatMode.Restart),typeConverter = Int.VectorConverter,initialValue = 0,targetValue = -textLayoutInfo.textWidth)// 根据动画帧时间,获取偏移量值。// 起始帧时间val startTime = withFrameNanos { it }do {val playTime = withFrameNanos { it } - startTimeoffset = animation.getValueFromNanos(playTime)} while (!animation.isFinishedFromNanos(playTime))// 延迟重新播放delay(delay)} while (true)}SubcomposeLayout(modifier = modifier.clipToBounds()) { constraints ->// 测量文本总宽度val infiniteWidthConstraints = constraints.copy(maxWidth = Int.MAX_VALUE)var mainText = subcompose(MarqueeLayers.MainText) {createText(textModifier)}.first().measure(infiniteWidthConstraints)var gradient: Placeable? = nullvar secondPlaceableWithOffset: Pair? = nullif (mainText.width <= constraints.maxWidth) {// 文本宽度小于容器最大宽度, 则无需跑马灯动画mainText = subcompose(MarqueeLayers.SecondaryText) {createText(textModifier.fillMaxWidth())}.first().measure(constraints)textLayoutInfoState.value = null} else {// 循环文本增加间隔val spacing = constraints.maxWidth * 2 / 3textLayoutInfoState.value = TextLayoutInfo(textWidth = mainText.width + spacing,containerWidth = constraints.maxWidth)// 第二遍文本偏移量val secondTextOffset = mainText.width + offset + spacingval secondTextSpace = constraints.maxWidth - secondTextOffsetif (secondTextSpace > 0) {secondPlaceableWithOffset = subcompose(MarqueeLayers.SecondaryText) {createText(textModifier)}.first().measure(infiniteWidthConstraints) to secondTextOffset}// 测量左右两边渐变控件gradient = subcompose(MarqueeLayers.EdgesGradient) {Row {GradientEdge(gradientEdgeColor, Color.Transparent)Spacer(Modifier.weight(1f))GradientEdge(Color.Transparent, gradientEdgeColor)}}.first().measure(constraints.copy(maxHeight = mainText.height))}// 将文本、渐变控件 进行位置布局layout(width = constraints.maxWidth,height = mainText.height) {mainText.place(offset, 0)secondPlaceableWithOffset?.let {it.first.place(it.second, 0)}gradient?.place(0, 0)}}}/*** 渐变侧边*/@Composableprivate fun GradientEdge(startColor: Color, endColor: Color,) {Box(modifier = Modifier.width(10.dp).fillMaxHeight().background(brush = Brush.horizontalGradient(0f to startColor, 1f to endColor,)))}private enum class MarqueeLayers { MainText, SecondaryText, EdgesGradient }/*** 文字布局信息* @param textWidth 文本宽度* @param containerWidth 容器宽度*/private data class TextLayoutInfo(val textWidth: Int, val containerWidth: Int)

调用上述的方法

@Composable
fun TestScreen() {val content = "这是一段很长很长很长很长很长很长很长很长很长很长的跑马灯文字;"Column(modifier = Modifier.padding(top = 200.dp)) {MarqueeText(text = content,color = Color.Black,fontSize = 24.sp,modifier = Modifier.padding(start = 50.dp, end = 50.dp).background(Color.White))}
}

实现启动类

class test : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {MyApplicationTheme {// A surface container using the 'background' color from the themeSurface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {TestScreen()}}}}
}

在xml启动文件中,添加这个kt文件


实现效果

在这里插入图片描述

4.总结

Compose框架是个高效率的安卓开发框架,它能避免xml的layout写法的繁琐、易错和难以调试,并且它提供了丰富的API供开发者使用,使得开发者能够将大量时间用于面向过程编程与面向结果编程,减少面向切片编程。

曾建城 https://blog.csdn.net/weixin_57235263/article/details/128127787?spm=1001.2014.3001.5501

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...