android | 声明式编程!(笔记)
https://www.jianshu.com/p/c133cb7cac21 讲的不错
命令式UI (how to do)
声明式UI (what to do) what to do
也许有人会说Data Binding不是可以让XML自己"动"起来吗?没有错,Data Binding其实就是Compose诞生之前的一种声明式U方案,谷歌曾经寄希望于通过它来提升U编码效率。
但是Compose推荐Composable使用首字母大写的名词来命名,且不允许有返回值。
组合优于继承
@Composable
fun HelloComposable() {
var content by rememberSaveable { mutableStateOf("") }
HelloContent(content = content, onContentChange = { content = it })
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HelloContent(content: String, onContentChange: (String) -> Unit) {
Column {
Text(text = "Hello $content")
OutlinedTextField(
value = content,
onValueChange = onContentChange,
label = { Text(text = content) }
)
}
}
//================================
Jetpack Compose 遵循单向数据流原则(unidirectional data flow),这是一种用于管理状态和数据更新的设计模式,特别适合用于构建用户界面。在这种模式下,所有的数据更新都应当遵循单个方向的流动,这有几个重要的好处:
预测性和可理解性: 当数据和状态变化总是以相同的方式流动时,应用的行为变得更加可预测和易于理解。这使得开发者更容易追踪数据流,理解数据是如何、以及在何处被更新的。
简化状态管理: 在单向数据流中,数据和状态的更新通常集中在特定的地点进行管理,减少了在应用各处分散更新数据引起的混乱和错误。
容易调试: 由于数据流的一致性,当出现问题时更容易定位和修复错误,因为开发者可以清晰地了解数据从哪里来,以及应该在哪里进行修改。
在代码示例中,content是作为单一数据源存在的,其值由HelloComposable管理,且通过参数传递到HelloContent中。当在OutlinedTextField中进行输入时,通过onValueChange事件回调更新外部content的状态,从而触发重新渲染(或称为重组,recomposition)过程。由此,我们可以看到数据(content值)是从上层流向下层的,而事件(用户的输入事件)则是从下层流向上层的,导致状态更新并触发重组。
这种模式确保了组件的UI始终与其状态保持一致,同时也使得状态的更新逻辑变得更加集中和清晰。
//================================
单一数据源决定了Composable数据流的单向流动,数据(content)总是自上而下流动,而事件(onContentChange)总是自下而上传递 为什么呢?
事件(如onContentChange)在Jetpack Compose(或任何现代UI框架)中自下而上传递的概念,主要体现在事件处理和状态管理方面。以OutlinedTextField组件中的onValueChange事件为例,来解析这一点:
事件回调的定义:在OutlinedTextField组件中,使用onValueChange属性定义了一个事件回调。当用户在文本字段中输入文本时,这个回调函数被触发。
状态更新:onValueChange通常会被设定为一个更新上层状态的函数,即在您的例子中的onContentChange。这意味着当OutlinedTextField中的事件(例如文本更改)发生时,它会调用onContentChange,这一回调函数随后可能会更新应用的状态(如,更新一个由父组件维护的content变量)。
自下而上的数据流:OutlinedTextField(作为较“低”层的组件)通过事件(如用户输入)影响了上层状态(通过onContentChange更新content值)。尽管UI框架通常采用自上而下的数据流动(父组件到子组件的状态传递),事件处理却采用自下而上的方式传递,即从子组件回到父组件,并最终可能引起状态的更新和UI的重新渲染。
响应式UI:一旦上层状态(如content变量)被更新,这个改变通过自上而下的数据绑定(如value = content)自动反映回UI,更新相应组件的显示内容。这样,事件处理和状态管理形成了一个闭环,使得UI能夠实时响应用户的操作。
总结来说,事件(如onValueChange对应的onContentChange)自下而上的传递体现在它能够影响并更新上层状态,这种机制使得组件能够响应用户的互动,而更新的状态又通过数据绑定机制影响UI的显示,形成一个连贯的响应链条。
Compose 业务上能做的优化大体上就是这些了。总之我们就是我们要保持组件的颗粒度尽可能的小,容易变动的要独立出来,非常稳定的也要独立出来,尽量使用 Immutable 的数据结构。 如此之后, Compose 的流畅度还是非常不错的。
//================================
精简代码
编写更少的代码会影响到所有开发阶段:作为代码撰写者,需要测试和调试的代码会更少,出现 bug 的可能性也更小,您就可以专注于解决手头的问题;作为审核人员或维护人员,您需要阅读、理解、审核和维护的代码就更少。
与使用 Android View 系统(按钮、列表或动画)相比,Compose 可让您使用更少的代码实现更多的功能。无论您需要构建什么内容,现在需要编写的代码都更少了。以下是我们的一些合作伙伴的感想:
//================================
“对于相同的 Button 类,代码的体量要小 10 倍。”(Twitter)
“使用 RecyclerView 构建的任何屏幕(我们的大部分屏幕都使用它构建)的大小也显著减小。”(Monzo)
““只需要很少几行代码就可以在应用中创建列表或动画,这一点令我们非常满意。对于每项功能,我们编写的代码行更少了,这让我们能够将更多精力放在为客户提供价值上。”(Cuvva)
编写代码只需要采用 Kotlin,而不必拆分成 Kotlin 和 XML 部分:“当所有代码都使用同一种语言编写并且通常位于同一文件中(而不是在 Kotlin 和 XML 语言之间来回切换)时,跟踪变得更容易”(Monzo)
无论您要构建什么,使用 Compose 编写的代码都很简洁且易于维护。“Compose 的布局系统在概念上更简单,因此可以更轻松地推断。查看复杂组件的代码也更轻松。”(Square)
—— https://developer.android.google.cn/develop/ui/compose/why-adopt?hl=zh-cn
相关文章:
android | 声明式编程!(笔记)
https://www.jianshu.com/p/c133cb7cac21 讲的不错 命令式UI (how to do) 声明式UI (what to do) what to do 也许有人会说Data Binding不是可以让XML自己"动"起来吗?没有错,Data Binding其实就是Compose诞生之前的一种声明式U方案,谷歌曾…...

友力科技IDC机房搬迁方案流程分享
机房搬迁流程 系统搬迁实施流程包括:准备、拆卸、装运、安装、调试等五个流程,具体如下: 准备:包括相关人员和设备准备、新机房环境准备、网络环境、备份、现场所有设备打标签、模块、设备准备等准备工作。拆卸:主要只核心设备下…...

仿迪恩城市门户分类信息网discuz模板
Discuz x3.3模板 仿迪恩城市门户分类信息网 (GBK) Discuz模板 仿迪恩城市门户分类信息网(GBK)...

Windows 注册表是什么?如何备份注册表?
Windows注册表(Windows Registry)是微软Windows操作系统中的一个重要组件,用于存储系统和应用程序的配置信息和选项。下面就给大家详细讲解一下什么是注册表。 注册表的概念 Windows 注册表是一个集中管理的数据库,存储了系统、…...

B+树与索引解析
文章目录 B树与索引简介几个关键点应用案例场景描述索引创建查询操作更新操作并发处理 Python代码示例 B树与索引简介 B树是一种在计算机科学中广泛使用的自平衡的树数据结构,它能保持数据排序,并且搜索、插入和删除操作的时间复杂度都是O(log n)。B树被…...

华为认证hcna题库背诵技巧有哪些?hcna和hcia有什么区别?
大家都知道华为认证hcna是有题库供考生刷题备考的,但题库中海量的题目想要在短时间背诵下来可并不是一件容易的事情,这就需要我们掌握一定的技巧才行。华为认证hcna题库背诵技巧有哪些? hcna和hcna这二者又有什么区别呢?今天的文章将为大家进行详细解…...
【常用报文状态码】
常见的报文状态码如下 200 OK:客户端请求成功。 301 Moved Permanently:表示请求的资源已经被永久移动到了新的URL上; 302 Found:表示请求的资源已经被临时移动到了新的URL上; 304 Not Modified:表示客户…...

Linux命令详解
1.目录结构 2.history游览历史 3.命令行中的ctrl组合键 4.列出目录的内容 5.修改文件权限chmod 6.文件内容查看 文件管理 7.输出重定向:> 8.管道:| 9.清屏:clear 10.显示当前路径:pwd 11.创建目录:mkdir…...

在阿里云使用Docker部署MySQL服务,并且通过IDEA进行连接
阿里云使用Docker部署MySQL服务,并且通过IDEA进行连接 这里演示如何使用阿里云来进行MySQL的部署,系统使用的是Linux系统 (Ubuntu)。 为什么使用Docker? 首先是因为它的可移植性可以在任何有Docker环境的系统上运行应用,避免了在不通操作系…...
Spring Boot中的国际化(i18n)实现技巧
Spring Boot中的国际化(i18n)实现技巧 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!在开发多语言支持的应用程序时,国际化…...

vite-ts-cesium项目集成mars3d修改相关的包和配置参考
如果vite技术栈下使用原生cesium,请参考下面文件的包和配置修改,想用原生创建的viewer结合我们mars3d的功能的话。 1. package.json文件 "dependencies": {"cesium": "^1.103.0","mars3d": "^3.7.18&quo…...
「树莓派入门」树莓派基础04-VNC连接与配置静态IP
一、VNC连接配置 1. 启用VNC服务 在树莓派上,通过 raspi-config 工具启用VNC服务: sudo raspi-config在配置界面中选择 “Interfacing Options”,然后选择 “VNC” 并启用它。 2. 连接到VNC服务器 在电脑端安装VNC客户端,如V…...

JAVA编程题期末题库【中】
8.计算邮资 程序代码: public static void main(String[] args) {// 计算邮资//if多分支语句//创建对象java.util.Scanner inputnew java.util.Scanner(System.in); //提示输入用户,输入邮件的重量System.out.println("邮件的重量:");int wei…...
【十年JAVA搬砖路】——MYSQL备份使用mysqldump
使用mysqldump 备份 1.创建备份脚本 cat <<EOF > sqlback.sh source ~/.bashrc NLS_DATE_FORMAT"yyyy-mm-dd HH24:MI:SS"; export NLS_DATE_FORMAT NLS_LANGAMERICAN_AMERICA.ZHS16GBK;export NLS_LANGbackuptimedate %Y%m%d%H%M%S /usr/bin/mysqldump -u…...
MetaGPT全面安装与配置指南
文章目录 MetaGPT环境配置1.1 检查Python版本1.2 拉取MetaGPT仓库1.3 拉取源码本地安装1.4 MetaGPT安装成果全流程展示1.5 尝试简单使用 MetaGPT的API调用2.1 本地部署大模型尝试安装必要的依赖下载并配置大模型配置API服务 2.2 讯飞星火API调用获取API密钥安装讯飞星火SDK调用…...

云计算期末综合测试题
云计算综合测试题 单选题填空题判断题简答题 单选题 这里选择题,直接以填空题展示,并给出解析 Bigtable是(Google)开发的分布式存储系统 解析:分布式结构化数据表Bigtable是Google基于GFS和Chubby开发的分布式存储系统…...

vue3-cropperjs图片裁剪工具-用户上传图片截取-(含预览视频)
效果图 上传图片弹窗预览 对于这个上传图片样式可以参考 官方原代码 官网传送入口 Upload 上传 | Element Plus (element-plus.org) <template><el-uploadclass"upload-demo"dragaction"https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6…...

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第48课-可视化控制机器人
【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第48课-可视化控制机器人 使用dtns.network德塔世界(开源的智体世界引擎),策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引…...

Java Stream API揭秘:掌握List流操作,打造高效数据处理流程
序言 Java Stream API是Java 8中引入的一个非常重要的功能组成部分,它提供了一种声明式的处理数据集合的方法。它主要特点是基于函数式编程的理念,允许我们以更加简洁、高效的方式进行集合的处理、转换和过滤。通过Stream API,我们可以灵活地…...
最新Java面试题及答案(Java基础、设计模式、Java虚拟机(jvm))
文章目录 前言一、Java基础题1.什么是Java?2.Jdk和Jre和JVM的区别?3.Java语言有哪些特点?4.Java有哪些数据类型?5.switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String上?6.…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...

MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...