Jetpack Compose 架构层

点击查看:Jetpack Compose 架构层 官网

本页面简要介绍了组成 Jetpack Compose 的架构层,以及这种设计所依据的核心原则。

Jetpack Compose 不是一个单体式项目;它由一些模块构建而成,这些模块组合在一起,构成了一个完整的堆栈。通过了解组成 Jetpack Compose 的不同模块,您可以:

  • 使用适当的抽象级别来构建应用或库
  • 了解何时可以“降级”到较低级别,以获取更多的控制权或更高的自定义程度
  • 尽可能减少依赖项

Jetpack Compose 的主要层包括:
在这里插入图片描述
图 1. Jetpack Compose 的主要层。
每一层均基于较低的层逐级构建,并通过组合功能来创建更高级别的组件。每一层都是基于较低层的公共 API 构建的,用于验证模块边界,还支持您根据需要替换任何层。让我们自下而上地分析这些层。

运行时
此模块提供了 Compose 运行时的基本组件,例如 remember、mutableStateOf、@Composable 注释和 SideEffect。如果您只需要 Compose 的树管理功能,而不需要其界面,则可以考虑直接基于此层进行构建。

界面
界面层由多个模块(ui-text、ui-graphics 和 ui-tooling 等)组成。这些模块实现了界面工具包的基本组件,例如 LayoutNode、Modifier、输入处理程序、自定义布局和绘图。如果您只需要用到界面工具包的基本概念,则可以考虑基于此层进行构建。

基础
此模块为 Compose 界面提供了与设计系统无关的构建块,例如 Row 和 Column、LazyColumn、特定手势的识别等。您可以考虑基于基础层构建自己的设计系统。

Material
此模块为 Compose 界面提供了 Material Design 系统的实现,同时提供了一个主题系统以及若干样式化组件、涟漪效果指示元素和图标。在您的应用中使用 Material Design 时,不妨基于此层进行构建。

设计原则

Jetpack Compose 的一个指导原则是提供可以组合在一起的重点突出的小块功能片段,而不是几个单体式组件。这种方法有许多优点。

控制

更高级别的组件往往能完成更多操作,但您拥有的直接控制权较少。如果您需要更多控制权,可以“下拉”使用较低级别的组件。

例如,如果您想为某个组件的颜色添加动画效果,可以使用 animateColorAsState API:

val color = animateColorAsState(if (condition) Color.Green else Color.Red)

不过,如果您需要组件始终以灰色开头,则不能使用此 API。您可以改为下拉菜单使用较低级别的 Animatable API:

val color = remember { Animatable(Color.Gray) }
LaunchedEffect(condition) {color.animateTo(if (condition) Color.Green else Color.Red)
}

较高级别的 animateColorAsState API 本身基于较低级别的 Animatable API 构建而成。使用较低级别的 API 的过程更为复杂,但可提供更多的控制权。请选择最符合您需求的抽象化级别。

自定义

通过将较小的构建块组合成更高级别的组件,可大幅降低按需自定义组件的难度。例如,可以考虑使用 Material 层提供的 Button 的实现:

@Composable
fun Button(// …content: @Composable RowScope.() -> Unit
) {Surface(/* … */) {CompositionLocalProvider(/* … */) { // set LocalContentAlphaProvideTextStyle(MaterialTheme.typography.button) {Row(// …content = content)}}}
}

Button 由 4 个组件组合而成:

  1. Material Surface:用于提供背景、形状和点击处理方式等。
  2. CompositionLocalProvider:用于在启用或停用相应按钮时更改内容的 Alpha 值
  3. ProvideTextStyle:用于设置要使用的默认文本样式
  4. Row:用于为相应按钮的内容提供默认布局政策

为了使结构更加清晰,我们省略了一些参数和注释,但整个组件只有 40 行左右的代码,因为它只是组合了这 4 个组件来实现该按钮。Button 等组件会自行判断它们需要公开哪些参数,同时在实现常见的自定义项和可能使组件更难使用的参数突增之间创造平衡。例如,Material 组件可提供 Material Design 系统中指定的自定义项,这样可以轻松遵循 Material Design 原则。

不过,如果您希望在组件参数之外进行自定义,则可以“降级”某个级别并复刻某个组件。例如,Material Design 指定按钮应具有纯色背景。如果您需要渐变背景,Button 参数就不适用了,因为它不支持此选项。在此类情况下,您可以将 Material Button 实现作为参考,并构建您自己的组件:

@Composable
fun GradientButton(// …background: List<Color>,modifier: Modifier = Modifier,content: @Composable RowScope.() -> Unit
) {Row(// …modifier = modifier.clickable(onClick = {}).background(Brush.horizontalGradient(background))) {CompositionLocalProvider(/* … */) { // set material LocalContentAlphaProvideTextStyle(MaterialTheme.typography.button) {content()}}}
}

上述实现继续使用 Material 层中的组件,例如 Material 的当前内容 Alpha 值和当前文本样式的概念。不过,它会将 Material Surface 替换为 Row 并设置其样式,以获得所需的外观。

注意:当“降级”到较低层以自定义组件时,请确保不会因忽视无障碍功能支持等原因而使任何功能发生降级。您要为哪个组件创建分支,就应以哪个组件作为指导。

如果您根本不想使用 Material 概念(例如,如果您要构建自己的定制设计系统),则可以选择仅使用基础层组件:

@Composable
fun BespokeButton(// …backgroundColor: Color,modifier: Modifier = Modifier,content: @Composable RowScope.() -> Unit
) {Row(// …modifier = modifier.clickable(onClick = {}).background(backgroundColor)) {// No Material components usedcontent()}
}

Jetpack Compose 为最高级别的组件保留了最为简洁的名称。例如,androidx.compose.material.Text 基于 androidx.compose.foundation.text.BasicText 构建。这样一来,如果您想替换更高级别,则可以为自己的实现提供更易于发现的名称。

注意:为组件创建分支意味着,您不会从上游组件的任何未来增补项或 bug 修复中受益。

选择合适的抽象化级别

Compose 以构建可重复使用的分层组件作为理念,这意味着您不应该始终以构建较低级别的构建块为目标。许多较高级别的组件不仅能够提供更多功能,而且通常还会融入最佳实践,例如支持无障碍功能等。

例如,如果您想为自己的自定义组件添加手势支持,可以使用 Modifier.pointerInput 从头开始构建;但在此之上还有其他更高级别的组件,它们可以提供更好的起点,例如 Modifier.draggable、Modifier.scrollable 或 Modifier.swipeable。

一般来讲,最好基于能提供您所需功能的最高级别的组件进行构建,以便从其包含的最佳实践中受益。

了解详情

如需查看构建自定义设计系统的示例,请参阅 Jetsnack 示例。

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

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

相关文章

Zookeeper简介及选举机制

1.概述 Zookeeper是一个开源的&#xff0c;分布式的&#xff0c;为分布式框架&#xff08;如下图中的Hadoop和Hive&#xff09;提供协调服务的Apache项目。 工作机制&#xff1a;基于观察者设计模式的分布式服务管理框架&#xff0c;负责存储和管理数据&#xff0c;接受观察者…

RabbitMQ 部署方式选择

部署模式 RabbitMQ支持多种部署模式&#xff0c;可以根据应用的需求和规模选择适合的模式。以下是一些常见的RabbitMQ部署模式&#xff1a; 单节点模式&#xff1a; 最简单的部署方式&#xff0c;所有的RabbitMQ组件&#xff08;消息存储、交换机、队列等&#xff09;都运行在…

2023年12月CCF-GESP编程能力等级认证C++编程七级真题解析

一、单选题(共15题,共30分) 第1题 定义变量 double x ,如果下面代码输入为 100 ,输出最接近( )。 A:0 B:-5 C:-8 D:8 答案:B 第2题 对于下面动态规划方法实现的函数,以下选项中最适合表达其状态转移函数的为( )。 A: B: C: D:

【自然语言处理-二-attention注意力 是什么】

自然语言处理二-attention 注意力机制 自然语言处理二-attention 注意力记忆能力回顾下RNN&#xff08;也包括LSTM GRU&#xff09;解决memory问题改进后基于attention注意力的modelmatch操作softmax操作softmax值与hidder layer的值做weight sum 计算和将计算出来的和作为memo…

C++ 学习之Set容器

C++ Set容器构造和赋值 在C++中,std::set是一个用于存储唯一元素的有序集合容器。下面介绍一下std::set容器的构造和赋值操作: 构造 std::set 默认构造函数: std::set<int> mySet; // 创建一个空的set使用初始化列表构造: std::set<int> mySet

【Java程序设计】【C00285】基于Springboot的游戏分享网站(有论文)

基于Springboot的游戏分享网站&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的游戏分享网站 本系统分为系统功能模块、管理员功能模块以及用户功能模块。 系统功能模块&#xff1a;在网站首页可以查看首页、游戏…

深入探究node搭建socket服务器

自从上篇中sokect实现了视频通话&#xff0c;但是是使用ws依赖库实现的服务端&#xff0c;所以最近再看ws源码&#xff0c;不看不知道&#xff0c;一看很惊讶。 接下来一点点记录一下&#xff0c;如何搭建一个简易的服务端socket&#xff0c;来实现上次的视频通讯。 搭建一个…

IP 电话

1 IP 电话概述 IP 电话是在互联网上传送多媒体信息。 多个英文同义词&#xff1a; VoIP (Voice over IP) Internet Telephony VON (Voice On the Net) 1.1 狭义的和广义的 IP 电话 狭义的 IP 电话&#xff1a;指在 IP 网络上打电话。 广义的 IP 电话&#xff1a;不仅仅是…

Linux学习方法-框架学习法——Linux应用程序编程框架

配套视频学习链接&#xff1a;https://www.bilibili.com/video/BV1HE411w7by?p4&vd_sourced488bc722b90657aaa06a1e8647eddfc 目录 Linux应用程序编程 Linux应用程序编程 Linux文件I/O(input/output) Linux文件I/O(五种I/O模型) Linux多进程 Linux多线程 网络通信(s…

【Spring】 AOP面向切面编程

文章目录 AOP是什么&#xff1f;一、AOP术语名词介绍二、Spring AOP框架介绍和关系梳理三、Spring AOP基于注解方式实现和细节3.1 Spring AOP底层技术组成3.2 初步实现3.3 获取通知细节信息3.4 切点表达式语法3.5 重用&#xff08;提取&#xff09;切点表达式3.6 环绕通知3.7 切…

真Unity3D编辑器Editor二次开发

IMGUI Editor Label 改变颜色 分享一个很神奇的颜色 一开始这么写&#xff0c;以为不行的&#xff0c; private void OnGUI()(){GUILayout.Label("<colorred>name:</color>ffdasilufoi");//。。。。 } 结果这么写又好了&#xff0c; private GUIStyle m…

【Leetcode】2583. 二叉树中的第 K 大层和

文章目录 题目思路代码结果 题目 题目链接 给你一棵二叉树的根节点 root 和一个正整数 k 。 树中的 层和 是指 同一层 上节点值的总和。 返回树中第 k 大的层和&#xff08;不一定不同&#xff09;。如果树少于 k 层&#xff0c;则返回 -1 。 注意&#xff0c;如果两个节点与根…