Jetpack Compose简介

news2024/10/7 6:40:03

文章目录

  • Jetpack Compose简介
    • 概述
    • 声明式UI和命令式UI
    • Jetpack Compose和Android View对比
    • Compose API设计原则
      • 一切皆为函数
      • 组合优于继承
      • 单一数据源
    • Jetpack Compose和Android View关系
    • 使用Compose
      • setContent()源码
      • @Composable
      • @Preview

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 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设计原则

一切皆为函数

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 Compose和Android View关系

在这里插入图片描述

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

使用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? ComposeView

    if (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 attach
        setParentCompositionContext(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 present
        setOwners()
        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.coloradmin.cn/o/1632404.html

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

相关文章

数据结构-二叉搜索树(BST)

目录 什么是二叉搜索树 二叉搜索树的特性 (1)顺序性 (2)局限性 二叉搜索树的应用 二叉搜索树的操作 (1)查找节点 (2)插入节点 (3)删除节点 (4)中序遍历 什么是二叉搜索树 如图所示&#xff0c;二叉搜索树&#xff08;binary search tree&#xff09;满足以下条件。…

Unity 递归实现数字不重复的排列组合

实现 private void Permutation(List<int> num, int leftIndex, List<string> strs) {if (leftIndex < num.Count){for (int rightIndex leftIndex; rightIndex < num.Count; rightIndex){Swap(num, leftIndex, rightIndex);Permutation(num, leftIndex 1…

【深度学习】【Lora训练1】StabelDiffusion,Lora训练过程,秋叶包,Linux,SDXL Lora训练

文章目录 一、环境搭建指南二、个性化安装流程三、启动应用四、打开web五、开始训练 19.27服务器 一、环境搭建指南 打造一个高效且友好的开发环境&#xff1a; 项目源码获取&#xff1a; 通过以下命令轻松克隆项目及所有子模块至您的Linux系统&#xff1a; git clone --recu…

workminer之dht通信部分

workminer是通过SSH爆破传播的挖矿木马&#xff0c;感染后会释放xmrig挖矿程序利用主机的CPU挖取北方门罗币。该样本能够执行特定的指令&#xff0c;指令保存在一个配置文件config中&#xff0c;config文件类似于xml文件&#xff0c;里面有要执行的指令和参数&#xff0c;样本中…

服务注册与发现Eureka、Zookeeper、Consul 三个注册中心的异同点(CAP理论)

Eureka Eureka是由Netflix开源的一个服务注册和发现组件&#xff0c;它主要用于构建高可用、分布式系统的基础设施中。Eureka的服务器端被称为Eureka Server&#xff0c;客户端则是那些需要注册的服务。Eureka具有以下特点&#xff1a; 高可用性&#xff1a;Eureka支持多节点…

小米汽车充电枪继电器信号

继电器型号&#xff1a; 参考链接 小米SU7&#xff0c;便捷充放电枪拆解 (qq.com)https://mp.weixin.qq.com/s?__bizMzU5ODA2NDg4OQ&mid2247486086&idx1&sn0dd4e7c9f7c72d10ea1c9f506faabfcc&chksmfe48a110c93f2806f6e000f6dc6b67569f6e504220bec14654ccce7d…

Linux网络开发基础知识

一个网络服务器的简单实现 项目需求 实现回声服务器的客户端/服务器程序&#xff0c;客户端通过网络连接到服务器&#xff0c;并发送任意一串英文信息&#xff0c;服务器端接收信息后&#xff0c; 将每个字符转换为大写并回送给客户端显示。 eoch_client.c #include <arpa/i…

Android双向认证配置过程

1&#xff08;可以绕过&#xff09;准备过程 为了让这个教程可以一直复用&#xff0c;打算直接写一个双向认证的APP作为素材。 工具&#xff1a; ●protecle&#xff08;签名文件转换&#xff09; ●keytool&#xff08;java自己就有&#xff09; ●openssl&#xff08;apache里…

前端canvas项目实战——在线图文编辑器(九):逻辑画布

目录 前言一、 效果展示二、 实现步骤1. 调整布局&#xff0c;最大化利用屏幕空间2. 添加逻辑画布3. 添加遮罩4. 居中显示逻辑画布5. 一个容易被忽视的bug点 三、Show u the code后记 前言 上一篇博文中&#xff0c;我们实现了一组通用的功能按钮&#xff1a;复制、删除、锁定…

LeetCode-hot100题解—Day5

原题链接&#xff1a;力扣热题-HOT100 我把刷题的顺序调整了一下&#xff0c;所以可以根据题号进行参考&#xff0c;题号和力扣上时对应的&#xff0c;那么接下来就开始刷题之旅吧~ 1-8题见LeetCode-hot100题解—Day1 9-16题见LeetCode-hot100题解—Day2 17-24题见LeetCode-hot…

httpClient提交报文中文乱码

httpClient提交中文乱码&#xff0c;ContentType类型application/json 指定提交参数的编码即可 StringEntity se new StringEntity(paramBody.toJSONString(),"UTF-8");se.setContentType("application/json");context.httpPost.setHeader("Cookie&…

Go-Zero从0到1实现微服务项目开发(二)

前言 书接上回&#xff0c;继续更新GoZero微服务实战系列文章。 上一篇被GoZero作者万总点赞了&#xff0c;更文动力倍增&#xff0c;也建议大家先看巧一篇&#xff0c;欢迎粉丝股东们三连支持一波&#xff1a;Go-zero微服务快速入门和最佳实践&#xff08;一&#xff09; 本…

Windows Server 2022 OVF, updated Apr 2024 (sysin) - VMware 虚拟机模板

Windows Server 2022 OVF, updated Apr 2024 (sysin) - VMware 虚拟机模板 2024 年 4 月版本更新&#xff0c;现在自动运行 sysprep&#xff0c;支持 ESXi Host Client 部署 请访问原文链接&#xff1a;Windows Server 2022 OVF, updated Apr 2024 (sysin) - VMware 虚拟机模…

从Kernel启动到Android系统整个过程源码分析

1、 第一阶段&#xff1a; 对于ARM的处理器&#xff0c;内核第一个启动的文件是arc/arm/kernel下面的head.S文件。当然arc/arm/boot/compress下面也有这个文件&#xff0c;这个文件和上面的文件略有不同&#xff0c;当要生成压缩的内核时zImage时&#xff0c;启动的是后者&…

企业如何保证内部传输文件使用的工具是安全的?

企业内部文件的频繁交换成为了日常运营不可或缺的一环。然而&#xff0c;随着数据量的爆炸式增长和网络攻击手段的日益复杂&#xff0c;内网文件传输的安全隐患也日益凸显&#xff0c;成为企业信息安全的薄弱环节。本文将探讨内网文件传输的安全风险、企业常用的防护措施。 内网…

《Fundamentals of Power Electronics》——Buck、Boost、Buck-Boost三个电路的CCM-DCM工作特性总结

Buck、Boost、Buck-Boost这三个电路的CCM-DCM工作特性总结如下表所示&#xff1a; Buck、Boost、Buck-Boost这三个电路工作在DCM模式下电压传输比的对比图如下所示&#xff1a; 由上图可知&#xff0c;Buck-Boost电路的工作特性是一条斜率为的直线&#xff0c;Buck电路和Boost电…

小长假来临,企业借助巡检系统做好安全巡查工作

节前节后是安全隐患事故多发期&#xff0c;小长假来了&#xff0c;企业面临着员工离岗、生产活动减少等特殊情况&#xff0c;这可能导致一些安全隐患被忽视。因此&#xff0c;借助巡检系统做好全面安全巡查工作显得尤为重要。巡检系统可以帮助企业实现巡检工作的规范化、标准化…

八_实验1:创建 VLAN 和划分端口

1、实验目的 通过本实验可以掌握&#xff1a; VLAN的概念。创建VLAN的方法。把交换机端口划分到VLAN中的方法。 2、实验​​​​​​拓扑 创建 VLAN 和划分端口的实验拓扑如下图所示。 图8-5 创建 VLAN 和划分端口的实验拓扑 3、实验步骤 &#xff08;1&#xff09;实验准…

C++:map和set的封装

关于红黑树的模拟实现&#xff0c;大家不清楚的先去看看博主的博客再来看这篇文章&#xff0c;因为set和map的封装底层都是利用用的红黑树。所以这里不会过多介绍红黑树的相关内容&#xff0c;而更多的是去为了契合STL中的红黑树去进行改造&#xff0c;让封装的set和map能够去复…

第二篇:Python环境搭建:从初学者到专家

Python环境搭建&#xff1a;从初学者到专家 在编程的世界里&#xff0c;准备好一个高效而舒适的开发环境是走向成功的第一步。在这篇博客文章中&#xff0c;我们将一起探索如何为Python编程搭建一个理想的环境。无论你是完全的新手还是希望提升现有的技能&#xff0c;本文都会…