Jetpack Compose简介

server/2024/9/23 4:43:42/

文章目录

Jetpack_Compose_2">Jetpack Compose简介

概述

Jetpack Compose是谷歌推出的全新Android UI开发框架,它采用更为先进的声明式开发思想,极大地提升了应用界面的开发效率,Compose代码与基于Android View系统的传统代码可以共存。

声明式UI和命令式UI

  • 命令式用命令的方式告诉计算机如何去做事情(how to do),计算机通过执行命令达到结果。
  • 声明式直接告诉计算机用户想要的结果(what to do),计算机自己去想该怎么做。

Android View 属于命令式的编程范式,使用 XML 定义的布局是静态的,无法根据响应状态自行更新。开发者需要通过 findViewById 等获取视图对象,然后通过命令式的代码调用对象方法驱动UI变更;而 Jetpack Compose 采用声明式编程范式,开发者只需要根据状态描述UI,当状态变化时,UI会自动更新。

Jetpack_ComposeAndroid_View_19">Jetpack Compose和Android View对比

Android View劣势:

  • 代码臃肿:View.java本身也变得越发臃肿,目前已超过三万行,早已不堪重负。臃肿的父类视图控件也造成了子类视图功能的不合理。以最常见的Button类为例,为了能让按钮具备显示文字的功能,Button被设计成了继承自TextView的子类:这显然是不合理的。
  • 兼容性差:像Button这类基础控件只能跟随系统的升级而更新,即使发现了问题也得不到及时修复,长期下来积重难返,破窗效应也越发突出。如今很多新的视图组件都以Jetpack扩展库的形式单独发布,目的也是为了不受系统版本的制约。

Jetpack Compose优势:

  • 先进的开发范式:Compose采用声明式的开发范式,开发者只需要聚焦在对UI界面的描述上,当需要渲染的数据发生变化时,框架将自动完成UI刷新。
  • 直观易用的API:基于Kotlin DSL打造的API紧贴函数式编程思想,相对于传统的视图开发方式,代码效率更高,实现同样的功能只需要以前一半的代码量。
  • 良好的兼容性:Compose代码与基于Android View系统的传统代码可以共存,用户可以按照喜欢的节奏将既有代码逐步过渡到Compose
  • 广泛的适用性:Compose最低兼容到API 21,支持市面上绝大多数手机设备的使用;Jetpack以及各种常用三方库也都第一时间与Compose进行了适配。
Android ViewJetpack Compose
类职责不单一,继承关系不合理函数声式编程,规避了面向对象的弊病
依赖系统版本,问题修复不及时独立迭代,良好的系统兼容性
命令式编程,开发效率低下声明式编程,DSL开发效率高

Compose_API_41">Compose API设计原则

一切皆为函数

Compose 声明式UI的基础是 Composable 函数,Composable 函数通过多级嵌套形成结构化的函数调用链,函数调用链经过运行后生成UI视图树;视图树一旦生成后不能随意改变,视图的刷新依靠 Composable 函数的反复执行实现。

说明:Kotlin编码规范中要求函数的首字母小写,但是 Compose 推荐 Composable 使用首字母大写的名词来命名,且不允许有返回值。这样在DSL中书写时可读性更好。有的 Composable 函数并不代表UI组件,此时可以遵循一般的函数命名规范。

组合优于继承

Android View 中的所有组件都直接或间接继承自 View 类,处于末端的子 View 会继承很多无用的功能。反观 Jetpack Compose,Composable 作为函数相互间没有继承关系,有利于促使开发者使用组合的视角思考问题。

在这里插入图片描述

单一数据源

传统的 Android View 中的 EditText,它的文字变化可能来自用户的输入,也有可能来自 setText() 方法,也就是所谓的多数据源,数据的变化不容易跟踪。而 Compose 则是数据是自上而下的单向流动,事件是自下而上传递。

Jetpack_ComposeAndroid_View_61">Jetpack Compose和Android View关系

在这里插入图片描述

  • Android View 是由 View 和 ViewGroup构成视图树。
  • Compose 是由 LayoutNode 构成视图树。ComposeView 继承自 AbstractComposeView,,ComposeView 负责对Android平台的Activity窗口的适配,AndroidComposeView 负责连接LayoutNode视图系统与View视图系统。

Compose_70">使用Compose

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {MyAndroidComposeTheme {Surface(modifier = Modifier.fillMaxSize(),color = MaterialTheme.colors.background) {Greeting("Android")}}}}
}@Composable
fun Greeting(name: String) {Text(text = "Hello $name!")
}@Preview(showBackground = true)
@Composable
fun DefaultPreview() {MyAndroidComposeTheme {Greeting("Android")}
}

使用 setContent() 方法替代以前的 setContentView() 方法。

setContent()源码

public fun ComponentActivity.setContent(parent: CompositionContext? = null,content: @Composable () -> Unit
) {val existingComposeView = window.decorView.findViewById<ViewGroup>(android.R.id.content).getChildAt(0) as? ComposeViewif (existingComposeView != null) with(existingComposeView) {setParentCompositionContext(parent)setContent(content)} else ComposeView(this).apply {// Set content and parent **before** setContentView// to have ComposeView create the composition on attachsetParentCompositionContext(parent)setContent(content)// Set the view tree owners before setting the content view so that the inflation process// and attach listeners will see them already presentsetOwners()setContentView(this, DefaultActivityContentLayoutParams)}
}

说明:setContent() 方法是 ComponentActivity 的一个扩展方法,通过Activity中的Window的DecorView获取到ContentView根布局,接着将 ContentView 的第一个子元素强转为 ComposeView,ComposeView 如果不存在则创建,然后通过 setContent() 给 ComposeView 设置内容,最后调用 setContentView()。

@Composable

@Composable 注解表示可组合函数,表示告知 Compose 编译器将该函数转换为界面。

@Preview

@Preview 注解表示可以在Android Studio中快速预览这些可组合函数的渲染结果,无需在设备或模拟器上运行应用。

annotation class Preview(val name: String = "",  // 名字val group: String = "",  // 分组@IntRange(from = 1) val apiLevel: Int = -1,  // API的等级val widthDp: Int = -1,  // 宽度val heightDp: Int = -1,  // 高度val locale: String = "",  // 语言设定@FloatRange(from = 0.01) val fontScale: Float = 1f, // 字体缩放比val showSystemUi: Boolean = false,  // 是否显示设备的状态栏和操作栏val showBackground: Boolean = false, // 是否显示背景val backgroundColor: Long = 0, // 背景颜色设置@UiMode val uiMode: Int = 0, // UI模式,比如深色模式@Device val device: String = Devices.DEFAULT  // 要在预览中使用的设备
)

使用:

@Preview(name = "测试", widthDp = 100, heightDp = 200, showBackground = true)
@Composable
fun DefaultPreview() {Greeting("Compose")
}

http://www.ppmy.cn/server/27745.html

相关文章

【LAMMPS学习】八、基础知识(5.1)有限尺寸球形和非球形粒子

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

ChatGPT 网络安全秘籍(三)

原文&#xff1a;zh.annas-archive.org/md5/6b2705e0d6d24d8c113752f67b42d7d8 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第五章&#xff1a;安全意识和培训 在这一章中&#xff0c;我们将深入探讨网络安全培训和教育的迷人领域&#xff0c;强调了 OpenAI 的大型…

Python 绘图边缘留白问题解决方案 / plt.savefig / plt.subplots_adjust 函数简析

文章目录 Part.I IntroductionPart.II 解决方案Chap.I plt.savefigChap.II plt.subplots_adjustChap.III plt.margins Part.III 探索历程Chap.I 默认保存方式Chap.II 使用 bbox_inches 参数控制Chap.III 自定义留白 Reference Part.I Introduction Python 绘图默认保存&#x…

GZIP文件格式解析和Inflate静态Huffman解压缩

GZIP是封装了Deflate压缩的格式文件&#xff1b;Deflate使用了无压缩、HuffmanLZ77进行压缩&#xff1b;解压是Inflate&#xff0c;Huffman包括静态Huffman压缩和动态Huffman压缩两种模式。 Java语言实现了GZIP格式解析、Inflate的静态Huffman解压缩、CRC32校验 算法。 gzip文…

镜像部署和服务器步署的介绍和不同点

镜像部署通常指的是使用Docker容器进行部署&#xff0c;而服务器部署则是指直接在服务器的操作系统上安装依赖并运行项目。下面是两种部署方式的介绍和它们的主要不同点&#xff1a; 镜像部署&#xff08;Docker&#xff09;&#xff1a; 环境隔离&#xff1a;Docker通过容器…

开源农场管理软件

软件介绍 Tania是一款基于Go、Vue.JS和SQLite的开源农场日记软件。该项目始于2016年11月&#xff0c;由于无法找到适合自己需求的软件&#xff0c;开发团队决定自己搭建一套适合家庭后院花园的管理系统&#xff0c;并可以随时随地进行管理。 项目功能描述 Tania是一款免费且开源…

ArkTS开发原生鸿蒙HarmonyOS短视频应用

HarmonyOS实战课程“2024鸿蒙零基础快速实战-仿抖音App开发&#xff08;ArkTS版&#xff09;”已经于今日上线至慕课网&#xff08;https://coding.imooc.com/class/843.html&#xff09;&#xff0c;有致力于鸿蒙生态开发的同学们可以关注一下。 课程简介 本课程以原生鸿蒙Ha…

描述Vue实例的生命周期钩子函数

Vue实例的生命周期是指Vue实例从创建到销毁的过程&#xff0c;这个过程包括开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程。Vue.js提供了很多钩子函数&#xff0c;让我们可以在Vue实例的不同状态下添加自定义代码。这些钩子函数主要被分为四个…