Jetpack Compose 介绍和快速上手

Compose版本发展

19年,Compose在Google IO大会横空出世,大家都议论纷纷,为其前途堪忧。

21年7月Compose 1.0的正式发布,却让大家看到了Google在推广Compose上的坚决,这也注定Compose会成为UI开发的新风向。

23年1月 发布了1.4版本, 在不断更新迭代......

Compose是什么

Compose则是一个全新的UI库,隶属Jetpack中的一员,它的出现是为了重新定义Android UI的开发方式——声明式UI编程

Compose的优势

  • 声明式UI,它基于声明式的UI编程模型,当数据发生改变时,UI将自动刷新。这意味着不再需要编写命令式代码来控制 UI 的每一个细节
  • 去掉XML,完全解除了混合写法(xml+Java、kotlin)的局限性
  • 超强兼容性,大多数常用库(如Navigation、ViewModel和Kotlin协程)都适用于Compose,Compose 能够与现有 View 体系并存,你可以为一个既有项目引入 Compose
  • 加速开发,为我们提供了很多开箱即用的Material 组件,如果的APP是使用的material设计的话,那么使用Jetpack Compose 能让你节省不少精力。
  • 精简代码数量,减少bug的出现
  • 实时预览,Compose 预览机制可以做到与真机无异,真正的所见所即得

Compose和View的关系

Compose 是基于 Canvas渲染,它的原理是通过AndroidComposeViewdispatchDraw分发绘制,通过dispatchTouchEvent分发手势,来实现「在同一个 View 的内部完成整个 UI 组件树」的效果。

AndroidComposeView的作用是承上启下,作为Compose和View混合开发的桥梁,从而实现API互相调用的能力

Compose 是不会有能力上的天然限制的,也就是传统 View 方案能做的事 Compose 全都可以做,比如各种复杂的动画、手势、嵌套的多层级布局,Compose 都可以做到。

Compose 没有做出对等实现的只有 SurfaceView 和 TextureView 这两个类,它们是用于高速刷新的内容的,比如视频播放或者相机的取景器界面。需要使用原生的 SurfaceView 或者 TextureView

扩展: 直接在Android上使用skia引擎进行绘制UI,这样就和flutter完全一致了,不过google为了兼容原来的view没有选择skia这个方案,兼容性是有了,但是也限制了compose的性能。

声明式UI & 命令式UI

声明式UI和命令式UI是两种不同的编程风格。

在命令式UI中,需要手动构建一个全功能的UI实例,比如一个TextView文本,在随后UI发生变化时,调用set方法手动刷新UI。

fun timer(){var count = 0textView.setOnClickListener{count+=1textView.text = "count:${count}""}
}

而在声明式UI中,开发人员描述当前的UI状态,数据更新后UI的刷新交给Compose框架。

@Composable
fun Timer(){var count by remember { mutableStateOf(0) }Text(text = "count:${count}", modifier = Modifier.clickable(onClick = count++))
}

Compose项目集成

使用Jetpack Compose 来开始你的开发工作有2种方式:

  • 将Compose 依赖库添加到现有项目
  • 创建一个支持Jetpack Compose的新应用

gradle 配置

在app目录下的build.gradle 中将app支持的最低API 版本设置为21或更高,同时开启Jetpack Compose enable开关,代码如下:

kotlin编译器与Compose兼容性对应表

android {buildFeatures {compose = true}kotlinOptions {jvmTarget = "1.8"}composeOptions {kotlinCompilerExtensionVersion = "1.4.0"}
}

Compose依赖添加

  • 借助 Compose 物料清单 (BoM),只需指定 BoM 的版本,即可管理所有 Compose 依赖库版本
dependencies {implementation platform('androidx.compose:compose-bom:2023.01.00')implementation("androidx.compose.foundation:foundation")implementation 'androidx.compose.ui:ui'
}

android推出的BOM(Bill of Material的缩写)来简化我们添加compose依赖过于繁杂的问题

  • 为什么建议使用 BoM 管理 Compose 库版本?

    • compose的一系列依赖,版本众多,更新且又频繁,且又相互有所依赖,对于我们开发来说,理清这些层层次次关系足以头大,然后还有个致命问题,我们几个库使用不同版本,可能还会导致编译直接报错,出现依赖版本等冲突问题
    • 今后,Compose 库将单独进行版本控制,这意味着版本号将开始按照自己的节奏递增。每个库的最新稳定版本已经过测试,并保证能够很好地协同工作。不过,找到每个库的最新稳定版本可能比较困难,而 BoM 会帮助您自动使用这些最新版本
  • BoM 是否会自动将所有 Compose 库添加到我的应用中?

    • 不会。需要再应用中实际添加和使用 Compose 库,必须在模块(应用级)Gradle 文件(通常是 app/build.gradle)中将每个库声明为单独的依赖项行。

    • 使用 BoM 可确保应用中的任何 Compose 库版本兼容,但 BoM 实际上并不会将这些 Compose 库添加到您的应用中。

    • 更新 BoM 版本时,使用的所有Compose库都会自动更新到新版本。

VersionCatlogs 依赖添加

BOM与Compose依赖版本对应表

// settings.gradle....versionCatlogs{create('composeLibs'){// Bom与Compose依赖库版本对应关系// https://developer.android.com/jetpack/compose/bom/bom-mapping?hl=zh-cn// 目前使用的是Bom:2023.01.00,但其中foundation使用了1.4.0-beta02,是因为该版本中LazyVerticalStaggeredGrid// 才支持自定义跨列(spanCount)的能力library('bom','androidx.compose','compose-bom').version('2023.01.00')// material组件库,如下拉刷新library('material', 'androidx.compose.material', 'material').withoutVersion()// 基础ui组件库library('ui', 'androidx.compose.ui', 'ui').withoutVersion()// as预览library('preview', 'androidx.compose.ui', 'ui-tooling-preview').withoutVersion()library('tooling','androidx.compose.ui','ui-tooling').withoutVersion()// 基础能力库 modifier修饰符,列表library('foundation', 'androidx.compose.foundation', 'foundation').version('1.4.0-beta02')// icon及扩展library('icons', 'androidx.compose.material', 'material-icons-core').withoutVersion()library('icons-ext', 'androidx.compose.material', 'material-icons-extended').withoutVersion()library('activity-compose', 'androidx.activity', 'activity-compose').version('1.6.1')// activity 和 viewmodel的扩展library('viewmodel-compose', 'androidx.lifecycle', 'lifecycle-viewmodel-compose').version('2.5.1')bundle('compose', ['material', 'ui', 'preview','tooling','icons', 'icons-ext','foundation','activity-compose','viewmodel-compose'])}}

添加一个 Text 元素

首先,我们会在 onCreate 方法中添加一个 Text 元素来显示一个 Hello World! 的文本。

setContent 块定义了一个我们可以调用 Composable 函数的 avtivity 的布局,Composable 函数只能从其他的 Composable 函数中调用

Jetpack Compose 使用一个 Kotlin 编译器插件来将这些 Composable 函数转化为应用程序的 UI 元素。例如,由 Compose UI 库定义的 Text() 函数就可以在屏幕上显示一个文本标签。

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {Text("Hello world!")}}
}

定义一个 composable 函数

  • Jetpack Compose 是围绕着 Composable 函数建立的。要创建一个 Composable 函数,只需在函数名称中添加 @Composable 注解。

  • Composable 函数只能从其他 Composable 函数的范围内调用。

为了更好的理解,定义一个 MessageCard() 函数,它包含了一个 name 参数,并使用这个参数来配置文本元素

class ComposeActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {MessageCard("Hello world!!! Welcome to Compose")}}// Composable 函数一般用大写开头,为了和普通的函数作为区分@Composablefun MessageCard(name: String) {Text(text = name)}
}

  • Android Studio 可以让你在 IDE 中预览你的 Composable 函数,而不需要部署到设备上。

  • 但是有个限制, 需要预览的 Composable 函数必须不能有任何参数。因为这个限制,你不能直接预览 MessageCard() 函数。

  • 但是,你可以尝试写第一个叫 PreviewMessageCard() 的函数,它调用带有参数的 MessageCard()。在 @Composable 之前添加 @Preview 注解。
@Preview(showBackground = true)
@Composable
fun MessageCardPreview() {TestApplicationTheme {MessageCard("Hello world!!! Welcome to Compose")}
}

消息卡片的搭建

到目前为止,我们已经建立了我们的第一个 Composable 的函数和预览! 为了发现更多的 Jetpack Compose 功能,我们将构建一个简单的页面结构,其中包含可以通过一些动画展开的消息列表。

data class Message(val author: String, val body: String)// Composable 函数一般用大写开头,为了和普通的函数作为区分
@Composable
fun MessageCard(msg: Message) {Row {Text(text = msg.author)Text(text = msg.body)}
}@Preview(showBackground = true)
@Composable
fun MessageCardPreview() {TestApplicationTheme {MessageCard(msg = Message(author = "Hello Compose",body = "I am lovely-chubby"))}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/80284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

can‘t sync to target.

飞翔仿真器 无法 与S12单片机 建立联系,仿真时显示 cant sync to target. 但是使用仿真器与其他板子连接仿真是没问题的。 首先怀疑硬件问题:没发现问题; 然后,勇敢的点击菜单中 设置速度,根据自己晶振和建议设置如…

套接字通信之 端口

端口 端口的本质? 无符号短整型数-> unsigned short端口取值范围? 可以有多少个端口? 2的16次方取值范围:0 - 65535 端口的作用? 定位某台主机上运行的某个进程 在电脑上运行了微信和QQ,小明给我的的微信发消息,电脑上的微信就收到了消息&#…

C语言经典100例题(56-60)--画圆;画方;画线

目录 【程序56】题目:画图,学用circle画圆形 【程序57】题目:画图,学用line画直线。 【程序58】题目:画图,学用rectangle画方形。 【程序59】题目:画图,综合例子。 【程序60】题…

arcgis拓扑检查实现多个矢量数据之间消除重叠区域

目录 环境介绍: 操作任务: 步骤: 1、数据库和文件结构准备 2、建立拓扑规则 3、一直下一页默认参数后,进行拓扑检查 4、打开TP_CK_Topology,会自动带出拓扑要素,红色区域为拓扑错误的地方&#xff1…

upload-labs文件上传靶场实操

文章目录 1.Pass-012.Pass-023.Pass-034.Pass-045.Pass-056.Pass-067.Pass-078.Pass-089.Pass-0910.Pass-1011.Pass-1112.Pass-1213.Pass-1314.Pass-1415.Pass-1516.Pass-1617.Pass-1718.Pass-1819.Pass-1920.Pass-20 上传姿势总结: 1)改后缀名绕过 2)Content-Type绕…

flink-1.14.4启动报错setPreferCheckpointForRecovery(Z)v

从flink1.12升级到flink1.14,修改了pom.xml的flink-version,打包的时候发现报错: // 当有较新的 Savepoint 时,作业也会从 Checkpoint 处恢复env.getCheckpointConfig().setPreferCheckpointForRecovery(true); 于是屏蔽了这段配置…

微信小程序怎么隐藏顶部导航栏(navigationBar)变透明的解决方案

怎么隐藏小程序顶部导航栏(navigationBar)? 官网说:Navigation是小程序的顶部导航组件,当页面配置 navigationStyle 设置为 custom 的时候可以使用此组件替代原生导航栏。 那么,我们就知道这种效果是可以…

SpringMVC多文件上传

文章目录 一、文件上传1.1 导入pom依赖1.2 配置文件上传解析器1.3 设置文件上传表单1.4 实现文件上传 二、文件下载三、多文件上传四、JRebel的使用 一、文件上传 1.1 导入pom依赖 <commons-fileupload.version>1.3.3</commons-fileupload.version><dependency…

abortControllerMap: Map<string, AbortController>

abortControllerMap: Map&#xff1c;string, AbortController&#xff1e;AbortController 是一个用于控制和取消异步任务的接口。 在这里&#xff0c;AbortController 用作一个映射的值&#xff0c;与映射的键&#xff08;string 类型&#xff09;相关联。 AbortController 可…

redis设计规范

部分内容参考&#xff1a;阿里redis开发规范 同时&#xff0c;结合shigen在实习中的实践经验总结。 key的名称设计 可读性和管理性 业务名: 表名: id pro:user:1001简洁性 控制key的长度&#xff0c;可以用缩写 transaction -> tras拒绝bigkey 防止网卡流量、慢查询&…

React Native 环境配置(mac)

React Native 环境配置&#xff08;mac&#xff09; 1.Homebrew2.Node.js、WatchMan3.Yarn4.Android环境配置1.安装JDK2.下载AndroidStudio1.国内配置 Http Proxy2.安装SDK1.首先配置sdk的路径2.SDK 下载 3.创建模拟器4.配置 ANDROID_HOME 环境变量 5.IOS环境1.升级ruby&#x…

学校项目培训之Carla仿真平台之安装Carla

官网&#xff1a;http://carla.org/ 写在前面 由于安装都写了很多东西&#xff0c;所以我单独将安装弄出来记录一下。 如果你在安装9.12版本的时候遇到了很多问题&#xff0c;你可以考虑以下几点&#xff1a; - 楼梯可能不太行&#xff0c;需要更换&#xff0c;这是我实践得到的…

浅析Java责任链模式实现

一、概要 定义&#xff1a;责任链模式是一种行为设计模式&#xff0c; 允许你将请求沿着处理者链进行发送。收到请求后&#xff0c; 每个处理者均可对请求进行处理&#xff0c; 或将其传递给链上的下个处理者。 二、应用场景&#xff1a; 1.多条件流程判断&#xff1a;权限相关…

iOS开发之编译OpenSSL静态库

项目审查发现OpenSSL1.0.2d有漏洞&#xff0c;所以需要升级更新OpenSSL版本&#xff0c;借此机会&#xff0c;记录一下编译OpenSSL静态库的流程。 Xcode使用的是14.2&#xff0c;OpenSSL使用的是1.0.2u、1.1.1u&#xff0c;由于是对两个不同版本进行的编译操作&#xff0c;所以…

Linux服务器部署常用命令记录【持续更新】

介绍&#xff1a;最近服务器被人频繁攻击&#xff0c;留下一堆垃圾文件。重装后需要重新部署&#xff0c;才发现Linux的命令怎么这么碎。于是乎就产生了写这篇文章的想法。本文旨在记录常用的Linux部署需要使用的命令&#xff0c;另一篇关于Linux docker安装常用软件的文章&…

HTTP响应详解, HTTP请求构造及HTTPS详解

HTTP响应详解 认识 "状态码" (status code) 状态码表示访问一个页面的结果 . ( 是访问成功 , 还是失败 , 还是其他的一些情况 ...). 以下为常见的状态码 . 200 OK 这 是一个最常见的状态码, 表示访问成功 . 抓包抓到的大部分结果都是 200 例如访问搜狗…

C# byte[] 如何转换成byte*

目标:将byte[]转成byte*以方便使用memcpy [DllImport("kernel32.dll", EntryPoint "RtlCopyMemory", CharSet CharSet.Ansi)] public extern static long CopyMemory(IntPtr dest, IntPtr source, int size); private void butTemp_Click(object…

C语言实现通讯录 (附完整代码)

C语言实现通讯录 &#x1f340;实现一个通讯录&#xff1a;&#x1f340;通讯录的功能&#xff1a;&#x1f340;多文件实现&#x1f4ae;设计结构体——保存人的信息&#x1f4ae;初始通讯录&#x1f4ae;封装通讯录&#x1f4ae;define宏定义修改通讯录的最大容量初始化通讯录…

Gitlab仓库部署

Gitlab仓库部署 一、Gitlab的概述1、gitlab介绍2、gitlab主要功能3、gitlab和github的区别 二、部署环境1、安装依赖环境2、安装Postfix邮箱3、Gitlab优势4、Gitlab工作流程 三、Gitlab部署过程1、Yum安装Gitlab2、配置gitlab站点URL3、启动并访问Gitlab 四、Gitlab具体操作1、…

C++中的导入include,头文件,extern,main函数入口及相关编译流程

结论&#xff1a; 1&#xff1a;#include就是复制粘贴 2&#xff1a;C编译的时候&#xff0c;在链接之前&#xff0c;各个文件之间实际上没有联系&#xff0c;只有到了链接的阶段&#xff0c;系统才会到各个cpp文件中去找需要的文件&#xff1b; 一&#xff1a;include的作用…