Compose的一些小Tips - 可组合项的绘制

news2024/9/25 17:22:11

系列文章

Compose的一些小Tips - 可组合项的生命周期
Compose的一些小Tips - 可组合项的绘制(本文)
Compose的一些小Tips - 列表的优化

前言

本系列介绍Compose的一些常识,了解这些tips并不会让人摇身一变成为大佬,但可以帮助到一些学习Compose的安卓开发者避免一些误区,也是对Compose入门详解中遗漏的一个补充。本文介绍可组合项的绘制

View的绘制 ≈ 可组合项的绘制

在说可组合项之前,我们先说说原生view的绘制过程,面试时也经常问到,并且可组合项的展现和view的绘制过程非常的相似。
在这里插入图片描述

原生view的绘制

我们简单复习下原生view的三个主要的阶段,值得注意的是,每一个view的绘制,都会经历这必不可少的三个阶段

  • onMeasure( int , int ) 测量所有子view的大小
  • onLayout( boolean , int , int , int , int ) 再次测量所有子view的大小并分配所有的子元素的位置
  • onDraw(Canvas) 渲染内容

ps:可以看到onMeasure会进行一次测量,onLayout也会进行一次测量,这是二次测量,有兴趣的可以自行了解,因为和本文内容不相关

在这里插入图片描述

可组合项的绘制

可组合项的展现到屏幕前的三个阶段分别为

  • Composition (组合) ,这是Compose的一大特性,与view的绘制不同,Compose 会运行可组合函数并创建界面说明。
  • Layout(布局) , 测量所有子可组合项并分配所有子可组合项的位置,与view的绘制不同,这里的测量会包含view中onMeasure的测量
  • Drawing(绘制),渲染内容

在这里插入图片描述

Compose会根据跟踪可组合项中的状态智能的跳过重组时不必要(没发生过变化)的阶段,这也是Compose对性能的优化。

可组合项的绘制不同阶段对应的具体方法

对于view来说onMeasure这些方法都是view的实现方法,而可组合项中好像也没有叫Composition 的方法暴露出来,这是因为Compose都是基于可组合项和它的状态来绘制的,因此三个阶段的具体方法也是二者的结合。并且因为单向数据流的关系,可能会因为对组合的状态的监听而影响到测量和绘制阶段(也可能不影响,下面会举例),所以下面的例子都是讲的直接影响这个阶段的作用域,并不是只影响这个阶段的作用域,希望读者不要误解。

组合

@Composable 函数或 lambda 代码块中的状态改变时,Compose会监听到状态的改变并开始重组(重新绘制),这也涉及到可组合项的生命周期相关知识,如果不了解的可以去看下Compose的一些小Tips - 可组合项的生命周期,我这边直接说结论,就是状态如果改变了内容则组合会发生改变,影响可组合项的绘制,而内容如果没发生改变,则会跳过重组。

我们可以来看一个简单的例子

    var state by remember {
        mutableStateOf(0)
    }
    Column() {
        Text(text = "重组$state")
        Text(text = "不重组")
    }

在上诉例子中第一个Text会因为state 的改变而进行重新进行组合这个阶段,因此重新进行绘制,如果state 从 0 变为1 ,则在理想情况下第一个Text会经历组合和绘制阶段,但因为Text的大小和位置都没有发生变化,所以会跳过测量阶段,而第二个Text因为不涉及状态的变化,会跳过所有的阶段。

测量

我们可以再来看一个简单的例子理解影响到测量阶段的值

    var width by remember {
        mutableStateOf(10.dp)
    }
    var offsetX by remember { mutableStateOf(8.dp) }
    Text(
        text = "位置和大小发生变化",
        modifier = Modifier
            .width(width)
            .offset {
            IntOffset(offsetX.roundToPx(), 0)
        }
    )

在上诉的简单代码示例中,影响到可组合项大小的width 状态和影响到可组合项位置的offsetX 状态会使Compose进行可组合项的测量阶段,然后再进行绘制阶段。

绘制

而绘制阶段的最明显的作用范围用最简单的话来说就是每一次从屏幕上肉眼可见的变化,都经历了绘制阶段,包括上面两段示例代码,都经历了绘制阶段。

为什么≈

为什么说View的绘制是约等于可组合项的绘制而不是等于呢,上面其实已经吧答案说过了

  • view的绘制阶段是每个阶段都要进行的,哪怕什么都没有变化,只要执行了重绘,所有的阶段都会重新进行一遍。
  • Compose的可组合项会根据状态智能的跳过不需要的阶段,从而进行性能的优化

这是原生xml和Compose除了写法以外,原理的不同。

Compose的智能取决于写法

上面已经说过,Compose的可组合项会根据状态智能的跳过不需要的阶段,以优化性能,而这个智能就很有嚼头,如果写法对了,就会智能的跳过,如果写的不对,就会造成额外的开销,甚至因为Compose的代码还在发展中,还不够成熟,会比原生xml更消耗性能,这也是一些不愿意学习的读者所说的,“我跑起来性能就是比原生差,跨平台还不如选flutter,哪儿哪儿都不行,再看两年吧”。在写法错误情况下,Compose的性能确实不如原生xml的。

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

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

相关文章

大数据Flink(八十四):SQL语法的DML:窗口聚合

文章目录 SQL语法的DML:窗口聚合 一、滚动窗口(TUMBLE)

R 语言画图中英文字体解决方案

在某些时候,需要在 R 画图中添加中文,但是默认情况下,R 对中文的支持不好。这里推荐一个 showtext 的 R 包。如果需要将含有中文字体的图形保存为 pdf 文件,可以使用下面讲到的方案,最新版的showtext已经支持了 ggplot…

6.1 使用scikit-learn构建模型

6.1 使用scikit-learn构建模型 6.1.1 使用sklearn转换器处理数据6.1.2 将数据集划分为训练集和测试集6.1.3 使用sklearn转换器进行数据预处理与降维1、数据预处理2、PCA降维算法 代码 scikit-learn(简称sklearn)库整合了多种机器学习算法,可以…

已解决 Bug: SyntaxError - expected expression, got ‘<‘

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页: 🐅🐾猫头虎的博客🎐《面试题大全专栏》 🦕 文章图文并茂&#x1f996…

C# ref 学习1

ref 关键字用在四种不同的上下文中; 1.在方法签名和方法调用中,按引用将参数传递给方法。 2.在方法签名中,按引用将值返回给调用方。 3.在成员正文中,指示引用返回值是否作为调用方欲修改的引用被存储在本地,或在一般…

React 全栈体系(十)

第五章 React 路由 三、基本路由使用 7. 代码 - Switch 的使用 7.1 Test /* src/pages/Test/index.jsx */ import React, { Component } from reactexport default class Test extends Component {render() {return (<div><h2>Test....</h2></div>…

拓世AI|轻松涨粉的秘密武器!从选题到配图,AI工具让你事半功倍

2023年的小红书&#xff0c;发展趋势依旧昂扬向上。 最新数据显示&#xff0c;小红书拥有逾3亿的月活用户,且超过80%的用户集中在20-30岁年龄段。这代表什么?广大的年轻用户基数和消费能力!正处于购买力上升期的年轻人,是品牌最想抓住的目标用户。巨大的红利吸引了无数人下场…

自定义开发成绩查询小程序

在当今数字化时代&#xff0c;教育行业借助技术手段提高教学效果。作为老师&#xff0c;拥有一个自己的成绩查询系统可以帮助你更好地管理学生成绩&#xff0c;并提供更及时的反馈。本文将为你详细介绍如何从零开始搭建一个成绩查询系统&#xff0c;让你的教学工作更加高效和便…

MQ - 10 RocketMQ的架构设计与实现

文章目录 导图概述RocketMQ 系统架构协议和网络模块数据存储元数据存储消息数据生产者和消费者生产端消费端HTTP 协议支持和管控操作RocketMQ 从生产到消费的全过程总结导图 概述 RocketMQ 在功能、稳定性、性能层面都比 RabbitMQ 的表现更好 RocketMQ 系统架构 先来看一下 R…

驱动开发练习,platform驱动模型的使用

一.总线模型介绍 linux中将一个挂载在总线上的驱动的驱动模型分为三部分&#xff1a;device、driver和bus&#xff1b; device部分&#xff1a;用来保存设备信息对象&#xff0c;在内核中一个klist_device链表中进行管理&#xff1b; driver部分&#xff1a;用来保存驱动信息对…

Windows:虚拟内存的使用

文章目录 简介如何开启并设置虚拟内存如何查看虚拟内存参考文献 简介 windows里什么是虚拟内存&#xff1f; 其实类似Linux里的交换内存/交换页&#xff0c;即将硬盘上一块空间作为虚拟的内存&#xff0c;当物理内存不足时&#xff0c;则可以将不常用的数据从物理内存中转移到…

如何做到人声和背景音乐分离?记住这个宝藏网站~

在这个短视频盛行的时代&#xff0c;优质的背景音乐会让视频锦上添花&#xff0c;但也会造成类似的问题&#xff1a;想单独使用视频中的某一段人声&#xff0c;但会被背景音乐扰乱视听效果。这时就需要将人声和背景音乐进行分离了&#xff0c;下面来分享一个宝藏网站&#xff0…

CodeArts Check代码检查服务用户声音反馈集锦(5)

作者&#xff1a;gentle_zhou 原文链接&#xff1a;CodeArts Check代码检查服务用户声音反馈集锦&#xff08;5&#xff09;-云社区-华为云 CodeArts Check&#xff08;原CodeCheck&#xff09;&#xff0c;是自主研发的代码检查服务。建立在华为30年自动化源代码静态检查技术…

抖音seo矩阵系统源码分享-技术梳理

抖音seo源码&#xff0c;抖音seo矩阵系统源码技术搭建&#xff0c;抖音seo源码技术开发思路梳理搭建 抖音账号矩阵系统部分源代码分享 if (empty($video_item)) {$this->displayJsonError(参数错误);}$curr_platform json_decode($video_item[dv_platform], 1);$curr_plat…

StarRocks 社区:从初生到两周年的进化之路

2021 年 9 月 8 日&#xff0c;StarRocks 开源社区诞生。从第一天开始&#xff0c;我们怀揣着“打造世界一流的数据分析产品”的梦想&#xff0c;踏上了星辰大海的征途。 两年间&#xff0c;StarRocks 在 GitHub 上收获了 5.4K Stars&#xff0c;产品共迭代发布了 90 余个版本&…

数字化营销到底是什么?与传统营销有什么区别?

一、什么是数字化营销&#xff1f; 数字化 将许多复杂的、难以估计的信息通过一定的方式变成计算机能处理的0和1的二进制码&#xff0c;形成计算机里的数字孪生。物理世界被重构&#xff0c;被一一搬到数字化世界当中。 数字化营销 就是数字化的传播渠道去推广企业的产品&am…

GLTF编辑器如何快速重置模型原点

1、什么是模型原点&#xff1f; 模型原点是三维建模中的概念&#xff0c;它是指在一个虚拟三维空间中确定的参考点。模型原点通常位于模型的几何中心或基本组件的中心位置。如图所示&#xff1a; 可以看到模型的原点在模型的几何中心 2、模型原点的作用 知道了什么是模型原点&…

【Linux】Ubuntu美化主题【教程】

【Linux】Ubuntu美化主题【教程】 文章目录 【Linux】Ubuntu美化主题【教程】1. 安装优化工具Tweak2.下载自己喜欢的主题3. 下载自己喜欢的iconReference 1. 安装优化工具Tweak 首先安装优化工具Tweak sudo apt-get install gnome-tweak-tool安装完毕后在菜单中打开Tweak 然后…

spring的ThreadPoolTaskExecutor装饰器传递调用线程信息给线程池中的线程

概述 需求是想在线程池执行任务的时候&#xff0c;在开始前将调用线程的信息传到子线程中&#xff0c;在子线程完成后&#xff0c;再清除传入的数据。 下面使用了spring的ThreadPoolTaskExecutor来实现这个需求. ThreadPoolTaskExecutor 在jdk中使用的是ThreadPoolExecutor…

跨境电商运营的新趋势:自养号测评补单技术解析

当前阶段&#xff0c;亚马逊、速卖通、虾皮、lazada等主流跨境电商平台的主要推广方式仍然是广告投放&#xff0c;毕竟这是平台的主要收入来源之一。然而&#xff0c;随着越来越多的卖家进军跨境市场&#xff0c;市场竞争日趋激烈&#xff0c;传统的广告投入效果逐渐减弱。在这…