Jetpack Compose 介绍和快速上手

news2024/11/23 12:51:36

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 = 0
   textView.setOnClickListener{
     count+=1
     textView.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 函数一般用大写开头,为了和普通的函数作为区分
  @Composable
  fun 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.coloradmin.cn/o/1015747.html

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

相关文章

基于springboot+vue的便利店信息管理系统

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

IDEA最新激 20活23码

人狠话不多 大家好,最近Intelli Idea官方的校验规则进行了更新,之前已经成功激20活23的Idea可能突然无法使用了。 特地从网上整理了最新、最稳定的激20活23码分享给大家,希望可以帮助那些苦苦为寻找Idea激20活23码而劳累的朋友们。 本激23…

所有字母异位词

class Solution { public:vector<int> findAnagrams(string s, string p) {std::vector<int> idxs;// 先获取p的hash串std::string dstr getHash(p);for (int i 0; i<s.length(); i) {// 使用滑动窗口&#xff0c;每次截取p的长度串并hashstd::string sub_str…

【Shiro】基本使用

1、环境准备 1、Shiro不依赖容器&#xff0c;直接创建maven工程即可 2、添加依赖 <dependencies><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.9.0</version></depen…

华为云云耀云服务器L实例评测|部署宝塔及使用宝塔管理服务器

在昨天的文章中,我们了解了一些关系实例的概念性的东西,并且购买了服务器,然后登录上后进行了简单的操作,今天我将会按照官网给出的教程,进行部署宝塔及使用宝塔对服务器进行管理的实践,那么 就让我们开始吧! 第一步:购买华为云云耀云服务器L实例 这个可以参考我的上一篇文章,…

关于医疗器械的检测认证

医疗器械注册审评流程&#xff1f; 【每日分享23.7.27】医疗器械产品注册申报流程&#xff08;超详细版&#xff09;之注册申报受理及审评审批 - 知乎 (zhihu.com) 医疗器械注册审评流程&#xff08;附图&#xff09;_申报_咨询_机构 (sohu.com) 型式试验&#xff1f; 型式试验…

Python 图形化界面基础篇:获取文本框中的用户输入

Python 图形化界面基础篇&#xff1a;获取文本框中的用户输入 引言 Tkinter 库简介步骤1&#xff1a;导入 Tkinter 模块步骤2&#xff1a;创建 Tkinter 窗口步骤3&#xff1a;创建文本框步骤4&#xff1a;获取文本框中的用户输入步骤5&#xff1a;启动 Tkinter 主事件循环 完整…

少儿编程 2023年5月中国电子学会图形化编程等级考试Scratch编程四级真题解析(选择题)

2023年5月scratch编程等级考试四级真题 选择题(共10题,每题2分,共50分) 1、下列积木运行后的结果是 (说明:逗号后面无空格) A、我 B、爱 C、中 D、国 答案:B 考点分析:考查字符串相关积木的使用,逗号也是一个字符,所以两个连起来后第8个字符就是爱字,答案…

webpack:css-loader和style-loader关系

测试 当我们webpack 的 rules 啥都没配置的时候 const path require(path);module.exports {entry: ./src/index.js,output: {filename: index.js,path: path.resolve(__dirname, dist)},module: {rules: []} };我们在 js 中导入了 css&#xff0c;发现报错&#xff0c;因为…

Linux编译过程与交叉编译

一.GCC由来 GCC&#xff08;GNU编译器套件&#xff09;是一个自由开源的编程工具集&#xff0c;用于编译和链接C、C和其他编程语言的程序。它由理查德斯托曼&#xff08;Richard Stallman&#xff09;和其他自由软件基金会&#xff08;Free Software Foundation&#xff09;的…

leetcode229. 多数元素 II(java)

多数元素 II 题目描述Hash表记录 题目描述 难度 - 中等 leetcode229. 多数元素 II 给定一个大小为 n 的整数数组&#xff0c;找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&#xff1a;[3] 示例 2&#xff1a; 输入&#…

LeetCode 1584. 连接所有点的最小费用【最小生成树】

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

竞赛 基于机器视觉的行人口罩佩戴检测

简介 2020新冠爆发以来&#xff0c;疫情牵动着全国人民的心&#xff0c;一线医护工作者在最前线抗击疫情的同时&#xff0c;我们也可以看到很多科技行业和人工智能领域的从业者&#xff0c;也在贡献着他们的力量。近些天来&#xff0c;旷视、商汤、海康、百度都多家科技公司研…

使用电力系统稳定器 (PSS) 和静态 VAR 补偿器 (SVC) 提高瞬态稳定性(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

fastjson远程命令执行

fastjson远程代码执行 漏洞原因&#xff1a;fastjson在对json字符串反序列化的时候&#xff0c;会读取到type的内容&#xff0c;将json内容反序列化为java对象并调用这个类的setter方法。 1、搭建rmi服务 直接利用jndi-exploit工具 2、抓包改为POST。开启nc监听、发包 PO…

Python 函数的定义

视频版教程 Python3零基础7天入门实战视频教程 函数 函数是执行特定任务的一段代码&#xff0c;程序通过将一段代码定义成函数&#xff0c;并为该函数指定一个函数名&#xff0c;这样即可在需要的时候多次调用这段代码。 比如我们前面学到的range()函数&#xff0c;就是系统…

js dispatchEvent派发自定义事件

低版本IE浏览器不兼容 dispatchEvent使用 在标准浏览器提供了元素触发自定义事件的方法 element.dispatchEvent()&#xff0c;就是说&#xff0c;我们可以不用在DOM上点击按钮触发事件&#xff0c;在代码里通过 dispatchEvent&#xff08;&#xff09;就能触发事件。如下&…

【Shiro】入门概述

1.是什么 Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架。Shiro 可以完 成&#xff1a;认证、授权、加密、会话管理、与 Web 集成、缓存 等。借助 Shiro 您可以快速轻松 地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程序。 官网&…

使用 React Native 针对 Android 进行开发

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 概述 通过安装所需工具开始使用 React Native 创建新的 React Native 项目 本指南将有助于开始使用 Windows 上的…

【操作系统】聊聊进程间通信方式

作为操作系统软件治理的核心 进程&#xff0c;那么进程间通信的方式就非常重要&#xff0c;常见的比如管道、消息队列、共享内存、信号量、信号、Socket等。本篇主要简单介绍下 我们知道每个进程都有自己独立的用户空间&#xff0c;而内核空间是共享的。 管道 ps -ef | gre…