深度解析 Compose 的 Modifier 原理 -- ParentDataModifier

Android Compose Modifier 在 Android 的 Compose 框架中,`Modifier` 是一种非常强大且灵活的工具,它用于修饰 Compose UI 元素的行为、布局和外观。你可以用它来做很多事情,比如设置宽度、高度、点击事件、拖拽动作等。在这篇文章中,我们将详细讲解 `Modifier` 的用法,并带你逐步走过实际代码示例。 阅读详情

在这里插入图片描述


" Jetpack Compose - - Modifier 系列文章 "


    📑 《 深入解析 Compose 的 Modifier 原理 - - Modifier、CombinedModifier 》

    📑 《 深度解析 Compose 的 Modifier 原理 - - Modifier.composed()、ComposedModifier 》

    📑 《 深入解析 Compose 的 Modifier 原理 - - Modifier.layout()、LayoutModifier 》

    📑 《 深度解析 Compose 的 Modifier 原理 - - DrawModifier 》

    📑 《 深度解析 Compose 的 Modifier 原理 - - PointerInputModifier 》

    📑 《 深度解析 Compose 的 Modifier 原理 - - ParentDataModifier 》


其实原理性分析的文章,真的很难讲的通俗易懂,讲的简单了就没必要写了,讲的繁琐难懂往往大家也不乐意看,所以只能尽量想办法,找个好的角度(比如从 Demo 代码示例出发)慢慢带着大家去钻源码,如果确实能帮助到大家完全理解了文章所讲述到的源码理论,那就值了。

在正式开始分析 DrawModifier 之前,建议你先看看 【LayoutModifier 和 Modifier.layout 用法及原理】这篇文章,毕竟它是作为 Modifier 原理解析的第一篇文章,对你了解整个 Modifier 架构还是很有帮助的,或者说它是最基础的一篇文章,如果不熟悉,后面的系列 Modifier 你可能会看的比较费劲… …


ParentDataModifier 的作用

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            ComposeBlogTheme {
                Row() {
                    Box(Modifier.size(40.dp).background(Color.Red))
                    Box(Modifier.size(40.dp).background(Color.Green))
                    Box(Modifier.size(40.dp).background(Color.Blue))
                }
            }
        }
    }
}

这段代码很简单,横向布局显示三个 Box,效果如下:

在这里插入图片描述

如果我希望这三个方块可以平分横向布局的空间,该怎么做?

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            ComposeBlogTheme {
                Row() {
                    Box(Modifier.size(40.dp).background(Color.Red).weight(1f))
                    Box(Modifier.size(40.dp).background(Color.Green).weight(1f))
                    Box(Modifier.size(40.dp).background(Color.Blue).weight(1f))
                }
            }
        }
    }
}

只要给每个 Box 添加 Modifier.weight(1f) 即可,相当于传统布局里面 LinearLayout 的 android:layout_weight。


在这里插入图片描述


从效果来看,Modifier.weight() 与测量布局有关,那说明它内部是一个 LayoutModifier?我们来看下:

interface RowScope {
    @Stable
    fun Modifier.weight(
        /*@FloatRange(from = 0.0, fromInclusive = false)*/
        weight: Float,
        fill: Boolean = true
    ): Modifier
}

internal object RowScopeInstance : RowScope {
    @Stable
    override fun Modifier.weight(weight: Float, fill: Boolean): Modifier {
        require(weight > 0.0) { "invalid weight $weight; must be greater than zero" }
        return this.then(
            LayoutWeightImpl(
                ... ...
            )
        )
    }
}

then 套了一个 LayoutWeightImpl:

internal class LayoutWeightImpl(
    val weight: Float,
    val fill: Boolean,
    inspectorInfo: InspectorInfo.() -> Unit
) : ParentDataModifier, InspectorValueInfo(inspectorInfo) {
    ... ...
}

原来 Modifier.weight 是创建了一个 ParentDataModifier,而不是 LayoutModifier,难道 ParentDataModifier 是 LayoutModifier 的一个子接口?

interface ParentDataModifier : Modifier.Element {
    fun Density.modifyParentData(parentData: Any?): Any?
}

很明显,ParentDataModifier 就只继承了 Modifier.Element 接口,与 LayoutModifier 无关。


ParentDataModifier 实际上是一个辅助的 Modifier,用于给外层包裹的 Composable 使用的,更具体讲是提供给被设置的子组件的父组件在测量子组件的时候使用,让父组件能更好的测量子组件。

Row() {
    // ParentDataModifier 是提供给 Row 使用的帮助测量 Box
    Box(Modifier.size(40.dp).background(Color.Red).weight(1f))
    Box(Modifier.size(40.dp).background(Color.Green).weight(1f))
    Box(Modifier.size(40.dp).background(Color.Blue).weight(1f))
}

而 LayoutModifier 它只能作用于单一的组件,即对单一的组件处理测量布局,比如上面例子的 Box(),对 Box() 设置的 LayoutModifier 只会它自己生效。

Row() {
	// 三个组件都设置了 Modifier.weight(),依靠单一组件无法测量出需要多少宽度
	// 需要互相知道组件宽度才能确定自己宽度
    Box(Modifier.size(40.dp).background(Color.Red).weight(1f))
    Box(Modifier.size(40.dp).background(Color.Green).weight(1f))
    Box(Modifier.size(40.dp).background(Color.Blue).weight(1f))
}

为了能测量出子组件所需要的宽度/高度,Compose 提供了 ParentDataModifier 方案,让父组件协助计算测量。

所以:ParentDataModifier 虽然设置给子组件,但却是提供给父组件使用的数据,辅助子组件进行尺寸测量和绘制计算的。

硬全桥副边钳位管Vds电压凸台揭秘——寄生参数引发的导通异常 本文深入分析了硬全桥副边钳位管Vds电压凸台现象,揭示了寄生参数如何引发导通异常。通过波形分析和工程实践,详细解析了走线电感的蓄能效应和体二极管的接力作用,并提供了PCB布局优化、元件选型和驱动电路调整等解决方案,帮助工程师有效应对这一常见问题。 阅读详情

相关推荐

LiveGBS流媒体平台GB/T28181实战指南:海康NVR物联网卡摄像头注册失败全链路排查与抓包技巧

本文详细解析了LiveGBS流媒体平台中海康NVR物联网卡摄像头注册失败的常见问题及解决方案。通过全链路排查与抓包技巧,包括物联网卡配置、多网卡冲突处理、防火墙设置等,帮助用户快速定位并解决GB/T28181协议下的设备注册难题,提升流媒体平台部署效率。

weixin_29290947的博客 492

compose--修饰符Modifier

上次介绍了compose中大多数的标准组件,此外还有两个重要的组件:列表LazyColumn和LazyRow,以及约束布局ConstraintLayout,在使用它们之前,先来认识Modifier 修饰符Modifier Modifier之前已经运用过,它能做的事情很多,不仅仅是改变组件的样式,还能够改变组件的位置,以及自定义交互事件,关于Modifier的所有用法,可以查看官方文档:https:...

aruba的博客 3128

光耦CTR参数实战:如何避免误触发与功耗陷阱(附计算公式)

本文深入解析光耦CTR参数在电路设计中的关键作用,探讨如何平衡误触发风险与功耗表现。通过TLP521、PC817等常见型号的实测数据对比,提供不同工作状态下的选型策略和计算公式,帮助工程师优化设计,提升系统稳定性和能效。

2a4s6d8f0g的博客 323

Compose 修饰符 - 原理

/自定义测量和摆放//TODO...//去掉涟漪效果clickable(写法过于底层,基本没有太多场景我们需要使用。启动协程作用域): R等待用户输入事件。

HugMua的博客 2017

移动开发(一):使用.NET MAUI开发第一个安卓APP

它是.NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动和桌面应用。使用 .NET MAUI,可从单个共享代码库开发可在 Android、iOS、macOS 和 Windows 上运行的应用。.NET MAUI 是一款开放源代码应用,是 Xamarin.Forms 的进化版,从移动场景扩展到了桌面场景,并从头重新生成了 UI 控件,以提高性能和可扩展性。

IT技术分享社区 2708

Zemax操作--2(单透镜和双胶合透镜优化)

单透镜 要求 镜头数据里面的数量变化后要重新设计优化函数 设计 一、初始参数 按照要求输入波长、入瞳孔径、视场数据编辑器如图 物面--透镜前表面--透镜后表面--相面(镜头数据再插入一个面如图) 将2面曲率半径F数设置为10,zemax自动给出合适值 设置面2的边缘光线高度,zemax自动给出合适值 二、评价参数设置 将面1曲率半径设置为变量 再设置评价函数告诉zemax我们需要什么条件,评价函数默认即可 执行优化 双胶合透镜 要求 ...

lzy750750的博客 1万+

JetPack Compose 手写一个 Row 布局 | 自定义布局

介绍 Jetpack compose 如何自定义布局,通过学习自定义布局实现自己的Row的布局

knight康康的博客 2281

Matlab:常见涡旋光束仿真

代码: clc clear all close all %% 环形涡旋光束 N = 200; lambda = 632e-9; %波长为632nm k = 2*pi/lambda; %波数 w0 = 3; %束腰半径 x = linspace(-10,10,N); y = linspace(-10,10,N); [X,Y] = meshgrid(x,y); [t...

zzz997的博客 3万+

Compose:Modifier、CombinedModifier 和 ComposedModifier

Compose Modifier

Vincent的博客 570

uniapp:使用uni.request请求报错errMsg“:“request:fail abort statusCode:-1(uniApp使用uni.request向服务端接口发起请求失败报错)

解决request请求报错request:fail abort statusCode:-1,Uniapp打包到app后报错request:fail abort statusCode:-1,uniapp使用uni.request请求报错{“errMsg“:“request:fail abort statusCode:-1“}的解决办法,不是SSL证书问题,跳过ssl验证,解决https问题,Uniapp报错,小程序报错(含https解决方案)(真机预览问题)uni-app打包后不发请求的原因,uni-app真

✅ 精选推荐文章 3580

CloudCompare 二次开发(41)——点云重建三维凸包并计算体积

本文介绍了如何结合PCL与CloudCompare实现点云三维凸包的构建与可视化。通过代码集成,在CloudCompare界面添加功能按钮,实现点云数据转换、凸包构建、体积计算以及可视化显示。具体步骤包括:1) 在UI中添加功能按钮;2) 将点云数据转换为PCL格式;3) 使用PCL的ConvexHull算法构建三维凸包;4) 计算并显示凸包体积;5) 将结果以点云和网格形式可视化显示。最终实现了点云凸包的自动构建与体积计算功能,为点云处理提供了实用工具。

点云侠的博客 193

Jetpack Compose ParentDataModifier

要自定义 ParentDataModifier,首先我们要搞明白:对于父组件来说,怎么获取子组件设置的 ParentData?) { ... }fun MyRow() {Layout(// 遍历获取所有子组件的 ParentData...Layout 函数的参数类型是 MeasurePolicy,虽然不是函数类型,但由于 MeasurePolicy 是一个单抽象方法接口,所以传参时可以使用 lambda 表达式,相当于是创建了一个 MeasurePolicy 的匿名实现类。...

m0_59162559的博客 1043

2025年开源气象大模型的实现原理与实践指南

气象大模型在人工智能时代实现了革命性突破,通过深度学习技术以更低的计算成本达到甚至超越传统数值天气预报的精度。开源气象大模型的出现使得全球研究者和机构都能参与气象AI的创新。本文详细解析了开源气象大模型的实现原理,包括核心架构、数据准备、训练方法和实际预测流程,并提供了实践指南。核心架构主要采用Transformer、图神经网络和扩散模型,处理多模态数据融合和时空联合建模。数据体系构建涉及数据来源、预处理和增强策略。模型训练关键技术包括损失函数设计、分布式训练优化和训练过程监控。微调与领域适应策略包括迁移学

专注AI大模型,软件混淆,授权 1181

深度解析 Compose 的 Modifier 原理 -- PointerInputModifier

其实原理性分析的文章,真的很难讲的通俗易懂,讲的简单了就没必要写了,讲的繁琐难懂往往大家也不乐意看,所以只能尽量想办法,找个好的角度(比如从 Demo 代码示例出发)慢慢带着大家去钻源码,如果确实能帮助到大家完全理解了文章所讲述到的源码理论,那就值了。这篇文章,毕竟它是作为 Modifier 原理解析的第一篇文章,对你了解整个 Modifier 架构还是很有帮助的,或者说它是最基础的一篇文章,如果不熟悉,后面的系列 Modifier 你可能会看的比较费劲…

Fucking Android & Compose & Harmony & Spring Boot ... 1585

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【Update】深度解析 Compose 的 Modifier 原理 -- DrawModifier

其实原理性分析的文章,真的很难讲的通俗易懂,讲的简单了就没必要写了,讲的繁琐难懂往往大家也不乐意看,所以只能尽量想办法,找个好的角度(比如从 Demo 代码示例出发)慢慢带着大家去钻源码,如果确实能帮助到大家完全理解了文章所讲述到的源码理论,那就值了。

Fucking Android & Compose & Harmony & Spring Boot ... 1560

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

图解Compose Modifier实现原理 ,竟然如此简单!

/ 今日科技快讯 /近日,《2021抖音泛知识内容数据报告》发布。报告显示,过去一年抖音上的泛知识内容播放量年同比增长达74%。泛知识内容播放量已占平台总播放量的20%。近年来,抖...

郭霖 1513

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

深入Jetpack Compose——布局原理与自定义布局(四)ParentData

上一篇文章,我们接触了固有特性测量。这一篇,我们将探索ParentData ParentData 曾经的例子 让我们回忆一下第一篇文章中提到的例子,为了实现如下效果 我们当时使用了这样一串修饰符: Box(modifier = Modifier .fillMaxSize() .wrapContentSize(align = Alignment.Center) .size(50.dp) .background(C

FunnySaltyFish's Blog 470

Compose讲解-Modifier使用

Compose讲解-Modifier使用

听海的博客 612

Compose Modifier

一、Modifier简单使用 我们先拿XML中的FrameLayout做下对比,如下,我们在xml文件中定义了一个宽度填充满父容器,高度200dp,背景为黑色,内容边距为16dp的FrameLayout: <FrameLayout android:layout_width="match_parent" android:layout_height="200dp" android:background="#000000" a..

qq_39037047的博客 810

compose中的Modifier

Jetpack Compose 中的 Modifier 是用于修饰和配置组件的核心工具,可替代 XML 布局中的多种属性。它具有无侵入性、顺序敏感和可组合的特点,支持链式调用。常用 Modifier 分为布局(如 size、padding)、样式(如 background、clip)、交互(如 clickable)等功能。与 XML 相比,Modifier 执行顺序会影响效果(如 padding 和 background 的顺序),且不可变。开发者还可自定义 Modifier 扩展功能,实现更灵活的 UI

琦琦的博客 475

Compose笔记(七)--Modifier

这一节主要了解一下Compose中Modifier,它本质上是一个接口,用于描述如何修改一个可组合项(Composable)的外观和行为...

ljt2724960661的博客 1099

Jetpack Compose中的Modifier

Modifier修饰符是Jetpack Compose中用来修饰组件的,提供常用的属性,写布局时几乎所有Composable组件的大部分属性都可以用Modifier 来修饰。官方在开发Compose UI时,最初尝试过将所有属性全部以函数参数的形式提供,但是那样太多了,他们也尝试过像Flutter那样的方式,将属性也作为一个组件进行嵌套,但这样又很容易让人感到困惑,所以才诞生了Modifier,将大部分组件常用属性封装成Modifier的形式来提供,哪个组件需要就在哪个组件上应用。

川峰的博客 2515

Compose Modifier修饰符详细解说

本文会对Modifier修饰符进行详尽的解说,报你收货满满 本文git地址: https://github.com/ymeddmn/ModifierIntroduce Modifier Modifier 可以被翻译为修饰符,可以用来修饰以下内容: 更改可组合项的大小、布局、行为和外观 添加信息,如无障碍标签 处理用户输入 添加高级互动,如使元素可点击、可滚动、可拖动或可缩放 item 代码案例 第三节属性扩展中的案例都是基于本节中 item 方法的形参进行赋值得到的 item1 ite

ymeddmn的博客 4414

Jetpack Compose :彻底搞懂 Modifier

本文深入解析Jetpack Compose中的Modifier核心概念。Modifier作为UI构建的"魔法棒",通过链式调用实现组件大小、布局、行为和外观的调整。文章重点强调Modifier的执行顺序规则:从左到右依次生效,顺序不同会导致截然不同的效果(如padding在background前/后的差异)。提供常用Modifier分类速查(布局尺寸、外观装饰、交互事件),并通过圆形头像卡片的实战案例演示正确使用顺序。最后介绍了Modifier复用技巧,包括变量提取和扩展函数方式。核心要

cj641809386的专栏 1282

Compose 实践与探索十一 —— ParentDataModifier

)但是这样的话,在实现 modifyParentData() 的具体内容时,你需要去查阅 Box 的父组件 Row 的内部都用到了哪些 parentData,这是一件很麻烦的事情。因此,这种方式不可行。@Stable。

tmacfrank 1579

compose中 Modifier的使用

Jetpack Compose 中 Modifier 提供了丰富的尺寸调整方法,包括固定大小(size)、填充容器(fillMaxSize)、尺寸约束(sizeIn)和内容包裹(wrapContent)等。在Box布局中,fillMaxSize会强制Box变大,而matchParentSize仅匹配Box最终尺寸。开发者可根据不同场景选择合适的修饰符:固定尺寸用size(),填充容器用fillMaxSize(),背景遮罩用matchParentSize(),内容自适应用wrapContentSize(),响

琦琦的博客 407
上一篇: 深度解析 Compose 的 Modifier 原理 -- PointerInputModifier
下一篇: 【 OpenHarmony 北向开发随笔 】-- HDC 常用命令
DeepCoder_Mx
博客等级 码龄16年 1103粉丝 45原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值