Jetpack Compose 自定义组件完全指南
Jetpack Compose 自定义组件完全指南
Compose 的声明式 UI 范式为创建自定义组件提供了前所未有的灵活性。本指南将带你从基础到高级全面掌握 Compose 自定义组件的开发技巧。
一、自定义组件基础
1.1 基本结构
一个最简单的自定义组件:
@Composable
fun Greeting(name: String) {Text(text = "Hello, $name!")
}
1.2 组件参数设计原则
- 明确职责:每个组件应只做一件事
- 合理的默认值:为非必要参数提供默认值
- 命名规范:使用描述性名称,遵循 Kotlin 惯例
@Composable
fun CustomButton(text: String,onClick: () -> Unit,modifier: Modifier = Modifier,enabled: Boolean = true,icon: @Composable (() -> Unit)? = null
) {// 实现
}
二、布局与样式
2.1 自定义布局
使用 Layout
可创建完全自定义的布局:
@Composable
fun CustomLayout(modifier: Modifier = Modifier,content: @Composable () -> Unit
) {Layout(modifier = modifier,content = content) { measurables, constraints ->// 测量和布局逻辑val placeables = measurables.map { it.measure(constraints) }layout(constraints.maxWidth, constraints.maxHeight) {var yPos = 0placeables.forEach { placeable ->placeable.placeRelative(x = 0, y = yPos)yPos += placeable.height}}}
}
2.2 样式与主题
使用 MaterialTheme 实现主题化:
@Composable
fun ThemedComponent() {val colors = MaterialTheme.colorSchemeBox(modifier = Modifier.background(colors.primary).padding(16.dp)) {Text("主题化组件", color = colors.onPrimary)}
}
创建自定义主题系统:
object CustomTheme {val colors: CustomColors@Composableget() = LocalCustomColors.current
}@Composable
fun CustomTheme(colors: CustomColors = lightCustomColors(),content: @Composable () -> Unit
) {CompositionLocalProvider(LocalCustomColors provides colors,content = content)
}
三、状态管理
3.1 组件内部状态
@Composable
fun Counter() {var count by remember { mutableStateOf(0) }Button(onClick = { count++ }) {Text("Clicked $count times")}
}
3.2 状态提升
@Composable
fun Counter(count: Int,onIncrement: () -> Unit,modifier: Modifier = Modifier
) {Button(onClick = onIncrement,modifier = modifier) {Text("Clicked $count times")}
}
3.3 高级状态管理
@Stable
class CustomState(initialValue: Int
) {var value by mutableStateOf(initialValue)fun increment() { value++ }
}@Composable
fun rememberCustomState(initial: Int = 0) = remember {CustomState(initial)
}
四、交互与动画
4.1 手势交互
@Composable
fun DraggableBox() {var offsetX by remember { mutableStateOf(0f) }Box(modifier = Modifier.offset { IntOffset(offsetX.roundToInt(), 0) }.pointerInput(Unit) {detectDragGestures { change, dragAmount ->offsetX += dragAmount.x}}.size(100.dp).background(Color.Blue))
}
4.2 动画效果
@Composable
fun AnimatedComponent(visible: Boolean) {val alpha by animateFloatAsState(targetValue = if (visible) 1f else 0f,animationSpec = tween(durationMillis = 300))Box(modifier = Modifier.alpha(alpha).size(100.dp).background(Color.Red))
}
五、高级技巧
5.1 性能优化
@Composable
fun OptimizedList(items: List<String>) {LazyColumn {items(items, key = { it }) { item ->Text(item)}}
}
5.2 跨平台适配
@Composable
fun PlatformSpecificComponent() {val configuration = LocalConfiguration.currentval isWideScreen = configuration.screenWidthDp >= 600if (isWideScreen) {WideScreenLayout()} else {MobileLayout()}
}
5.3 测试策略
@Test
fun testCustomComponent() {composeTestRule.setContent {CustomButton(text = "Test", onClick = {})}composeTestRule.onNodeWithText("Test").assertIsDisplayed()
}
六、实战案例
6.1 自定义下拉刷新
@Composable
fun PullToRefreshLayout(refreshing: Boolean,onRefresh: () -> Unit,content: @Composable () -> Unit
) {Box(modifier = Modifier.pointerInput(Unit) {// 手势检测逻辑}) {content()if (refreshing) {CircularProgressIndicator()}}
}
6.2 复杂图表组件
@Composable
fun LineChart(dataPoints: List<Float>,modifier: Modifier = Modifier
) {Canvas(modifier = modifier) {// 自定义绘制逻辑}
}
七、最佳实践
- 组合优于继承:通过组合现有组件构建新组件
- 单向数据流:状态提升到可管理的层级
- 考虑重组:避免在组合函数中执行耗时操作
- 无障碍支持:添加适当的内容描述
- 主题适配:尊重用户的主题偏好
八、调试与优化
- 使用
Modifier.debugInspectorInfo
调试布局问题 - 通过
AndroidViewBinding
集成现有视图 - 使用
rememberSaveable
处理配置变更 - 利用
DerivedState
优化计算密集型操作
结语
掌握 Compose 自定义组件开发可以极大提升 UI 开发的灵活性和效率。从简单的布局组合到复杂的自定义绘制和动画,Compose 提供了完整的工具链来满足各种需求。记住在实践中不断尝试和优化,你会发现 Compose 的强大之处。
相关文章:
Jetpack Compose 自定义组件完全指南
Jetpack Compose 自定义组件完全指南 Compose 的声明式 UI 范式为创建自定义组件提供了前所未有的灵活性。本指南将带你从基础到高级全面掌握 Compose 自定义组件的开发技巧。 一、自定义组件基础 1.1 基本结构 一个最简单的自定义组件: Composable fun Greeti…...
ETF 场内基金是什么?佣金最低又是多少呢?
嘿,朋友们,大家好啊,我是StockMasterX,今天咱们就坐下来慢慢聊聊这个话题,ETF 场内基金到底是个啥东西,它的佣金最低能到多少,真的是个值得深挖的问题。 说起ETF,我还记得刚入行那会…...
【C++篇】类与对象(中篇) 解密C++类的核心:六大默认成员函数详解与避坑指南
文章目录 前言一、类的六个默认成员函数二、构造函数1. 概念2. 特性(牢记) 三、析构函数1. 概念2. 特性(牢记) 四、拷贝构造函数1. 概念2. 特性(牢记) 五、赋值运算符重载1. 运算符重载2. 赋值运算符重载前…...
001 vue
https://cn.vuejs.org/ 文章目录 v-bindv-modelv-on修饰符条件渲染/控制:v-if v-show列表渲染 M:即Model,模型,包括数据和一些基本操作 V:即View,视图,页面渲染结果 VM:即View-Mode…...
web forms可视化开发显示的网页是用ExpressionWebEditorFrame控件,是IE内核还是简单的HTML解析?如何让他加载CSS和JS?
web forms可视化开发显示的网页是用ExpressionWebEditorFrame控件,是IE内核还是简单的HTML解析?如何让他加载CSS和JS? 1. ExpressionWebEditorFrame 控件的内核及解析机制 在 Visual Studio 中用于 Web Forms 可视化开发的 ExpressionWebEditorFrame 控件主要基于 Internet…...
$R^n$超平面约束下的向量列
原向量: x → \overset{\rightarrow}{x} x→ 与 x → \overset{\rightarrow}{x} x→法向相同的法向量(与 x → \overset{\rightarrow}{x} x→同向) ( x → ⋅ n → ∣ n → ∣ 2 ) n → (\frac{\overset{\rightarrow}x\cdot\overset{\righta…...
英伟达新一代GPU架构(50系列显卡)PyTorch兼容性解决方案
随着NVIDIA不断推出基于新架构的GPU产品,机器学习框架需要相应地更新以支持这些硬件。本文记录了在RTX 5070 Ti上运行PyTorch时遇到的CUDA兼容性问题,并详细分析了问题根源及其解决方案,以期为遇到类似情况的开发者提供参考。 在Anaconda虚…...
16.2Linux自带的LED灯驱动实验(详细编写)_csdn
这个实验不用自己编写代码。 1、在linux源代码中,打开 stm32mp15-pinctrl.dtsi 文件并进行修改: make uImage LOADADDR0XC2000040 -j8 //编译内核然后: 2、修改设备节点,打开 stm32mp157d-atk.dts: 其中࿱…...
Java 大视界 -- Java 大数据在智慧交通停车场智能管理与车位预测中的应用实践(174)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
HashMap 底层原理详解
1. 核心数据结构 JDK 1.7 及之前:数组 链表 JDK 1.8 及之后:数组 链表/红黑树(链表长度 ≥8 时转红黑树,≤6 时退化为链表) // JDK 1.8 的 Node 定义(链表节点) static class Node<K,V&g…...
重生之我是去噪高手——diffusion model
diffusion model是如何运作的? 想象一下,你有一张清晰的图片。扩散模型的核心思想分为两个过程: 前向过程(Forward Process / Diffusion Process):逐步加噪反向过程(Reverse Process / Denois…...
FfreeRTOS有阻塞作用的API
在 FreeRTOS 中,阻塞 API 是指那些会导致调用任务进入阻塞状态(Blocked State)的函数,即任务会暂时让出 CPU,直到某个条件满足(如超时、信号量可用、队列数据到达等)。以下是常见的阻塞 API 分类及示例: 1. 任务延迟(延时) vTaskDelay() 使任务阻塞指定的时间(以系统…...
app逆向专题二:app逆向流程
app逆向专题二:app逆向流程 一、app逆向说明二、拿到APP应用的apk三、使用工具进行查壳四、有壳需要先进行脱壳,拿到dex文件进行反编译五、使用Jadx-Gui或其他工具进行反编译,分析源码;六、根据app的抓包情况拿到加密的关键词参数…...
VMware 安装 Ubuntu 全流程实战指南:从零搭建到深度优化
在软件开发、系统测试以及技术学习等诸多场景中,使用虚拟机安装操作系统是一种灵活且高效的方式。Ubuntu 作为一款优秀的开源操作系统,在 VMware 虚拟机上的安装与优化备受关注。接下来,将为大家带来 VMware 安装 Ubuntu 的全流程实战指南&am…...
论文阅读笔记——RDT-1B: A DIFFUSION FOUNDATION MODEL FOR BIMANUAL MANIPULATION
RDT-1B 论文 模型表达与泛化能力:由于双臂操作中动作空间维度是单臂空间的两倍,传统方法难以建模其多模态分布。 数据:双臂数据少且不同机器人的物理结构和动作空间差异(如关节数、运动范围)导致数据分布不一致&#x…...
如何一天背300到500个单词
买一本有结构分析或词源注释的目标词汇书。 买一盒口香糖。 准备一摞空白的A4纸。 找一间用于冥想的黑屋子(眼晴闭上就可以了)。 将要背诵的单词进行分组: 5个一小组10个一中组50个一大组100个一个基本包或单元。给自己一个约定,比如背完一中组或一大组单词,嚼一粒口香糖…...
vs环境中编译osg以及osgQt
1、下载 OpenSceneGraph 获取源代码 您可以通过以下方式获取 OSG 源代码: 官网下载:https://github.com/openscenegraph/OpenSceneGraph/releases 使用 git 克隆: git clone https://github.com/openscenegraph/OpenSceneGraph.git 2、下载必要的第三方依赖库 依赖库 ht…...
C++ - 头文件基础(常用标准库头文件、自定义头文件、头文件引入方式、防止头文件重复包含机制)
一、头文件 在 C 中,头文件(.h)用于函数声明、类定义、宏定义等等 在 Visual Studio 中,头文件通常放在头文件目录中,头文件实现通常放在源文件目录中 二、常用标准库头文件 1、输入输出 <iostream> 标准输入…...
12款字重国外法国风格复古报纸日历设计衬线英文字体安装包 Claire Font Family
Claire 是一个带有坚固衬线的字体系列。该系列中的几种粗细字体非常适合设置大量连续文本;另一方面,极轻和极重的字体在显示应用中配合使用效果很好。Clair 中的字体具有垂直轴,其设计让人联想到当代报纸字体以及 Century 模型中的十九世纪晚…...
Java 类型转换和泛型原理(JVM 层面)
一、类型转换 概念解释: 编译类型:在编译时确定,保存在虚拟机栈的栈帧中的局部变量表中; 运行类型:在运行时确定,由保存在局部变量表中变量指向的堆中对象实例的类型决定(存储在对象头中&…...
ffmpeg基础知识入门
文章目录 📦 1. **容器(Container)**✅ 定义:✅ 举例:✅ 功能: 📶 2. **媒体流(Stream)**✅ 定义:✅ 举例:✅ 流和容器关系: …...
k8s 1.23升级1.24
0、简介 这里只用3台服务器来做一个简单的集群,当前版本是1.23.17目标升级到1.24.17 地址主机名192.168.160.40kuber-master-1192.168.160.41kuber-master-2192.168.160.42kuber-node-1 我这里设置的master2可调度pod,将master2的污点去掉 kubectl de…...
MIPI与DVP接口摄像头:深度解析与应用指南
1、MIPI 1.1 MIPI简介 MIPI是什么?MIPI:mobile industry processor interface移动行业处理器接口。它是一个由Intel、Motorola、Nokia、NXP、Samsung、ST(意法半导体)和TI(德州仪器)等公司发起的开放标准…...
liunx输入法
1安装fcitx5 sudo apt update sudo apt install fcitx fcitx-pinyin 2配置为默认输入法 设置-》系统-》区域和语言 点击系统弹出语言和支持选择键盘输入法系统 3设置设置 fcitx-configtool 如果没显示需要重启电脑 4配置fcitx 把搜狗输入法放到第一位(点击下面…...
马吕斯定律(Malus‘s Law)
马吕斯定律(Maluss Law)详解 马吕斯定律是偏振光学中的基本定律,由法国物理学家**tienne-Louis Malus**于1809年发现,描述了**线偏振光**通过检偏器后的光强变化规律。 2. 实验验证 3. 数学推导 4. 关键应用 5. 特殊情况讨论 …...
大厂算法面试 7 天冲刺:第6天-树与图深度剖析——高频算法面试题 Java 实战
🧠 第6天:树与图深度剖析——高频算法面试题 & Java 实战 📚 一、核心知识概览 Overview 1. 树(Tree) 树是一种非线性数据结构,常见于面试中的二叉树(Binary Tree)、二叉搜索树…...
C语言编译和链接错题
一、错题重现 1.用在switch语句中的关键字不包含哪个?( ) A.continue B.break C.default D.case 2.下面代码的结果是:( ) A.3 B.4 C.随机值 D.5 3.下面那个不是转义字符? A.\n B.\060 C.\q D.\b 二、错因分析及思考 1.题目看…...
吴恩达深度学习复盘(7)一个简单训练示例
简介 本篇简单讲解简单的神经网络训练。通过回顾逻辑回归模型训练,了解神经网络训练的相关内容。比如训练步骤、损失函数、优化算法以及深度学习库的使用,了解训练过程中的相关概念。 例子 手写数字识别(判断是 0 还是 1)。这是…...
道路坑洼目标检测数据集-665-labelme
文章目录 1.介绍3.标签介绍4.标注工具5.数据集下载 1.介绍 目标:从道路图像中检测坑洼; 应用:检测道路地形和坑洼可实现平稳行驶,小型数据集常常用于学习和学术研究; 详细信息: 665 张图、1740个在坑洼处标…...
提升移动端用户体验:解决输入框被软键盘遮挡的有效方法
解决移动端输入框被软键盘覆盖的问题 在开发移动端网页时,如果页面包含输入框,则可能会遇到输入框被弹出的软键盘遮挡的问题。为了解决这个问题,我们需要理解两种常见的情况以及相应的解决策略。 浏览器未主动聚焦到输入框 现代浏览器和移…...
函数极限常见计算方法集锦
本文非常直接,如标题所见就是一个常见的计算方式极限方法的集锦。 所以内在逻辑性确实不强,主要通过例题的形式阐述。 添项减项 当题目出现了交错的形式便可以考虑添项减项。 一般而言我们会加一项交错项,减一项交错项。 例如出现 A B …...
Tomcat的部署
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和 并发访问用户不是很多的场合下被普遍使用,Tomcat 具有处理HTML页面的功能,它还是一个Servlet和 JSP容器 官网:Apache Tomcat - Welco…...
Ubuntu(CentOS、Rockylinux等)快速进入深度学习pytorch环境
这里写自定义目录标题 安装进入系统(如Ubuntu22.04)安装anacondapip、conda换源pip换源conda换源 安装nvidia安装pytorch环境针对于wsl的优化 安装进入系统(如Ubuntu22.04) docker 、 wsl 、 双系统 、服务器系统 推荐 Ubuntu 20…...
AI 如何帮助我们提升自己,不被替代
在当今快速发展的时代,人工智能(AI)正逐渐渗透到生活的方方面面。许多人担心 AI 会取代人类的工作,然而,AI 更多的是作为一种强大的赋能工具,帮助我们提升自身能力,让我们在工作中更具竞争力。以…...
ROS2 多机时间同步(Chrony配置简明指南)
适用场景: 主机运行 ROS2 Humble(发布 /scan 等),板子运行 ROS2 Foxy(发布 /tf 等),两边通过 ROS_DOMAIN_ID 跨平台通讯。需要保证系统时间对齐,避免 TF 插值失败、建图抖动等问题。…...
C 语言排序算法:从基础到进阶的全面解析一、引言
一、引言 在 C 语言编程领域,排序算法是一项基础且核心的技能。无论是处理海量数据,还是优化程序性能,选择合适的排序算法都至关重要。本文将深入剖析 C 语言中常见的几种排序算法,包括冒泡排序、选择排序、插入排序、希尔排序、…...
蓝桥云客--团队赛
2.团队赛【算法赛】 - 蓝桥云课 问题描述 蓝桥杯最近推出了一项团队赛模式,要求三人组队参赛,并规定其中一人必须担任队长。队长的资格很简单:其程序设计能力值必须严格大于其他两名队友程序设计能力值的总和。 小蓝、小桥和小杯正在考虑报名…...
VBA第三十八期 VBA自贡分把表格图表生成PPT
上一节讲到把数据区域自动生成PPT,这一实例是把图表自动生成PPT。 Sub CopyA11ChartsToPresenta() Dim PP As PowerPoint. Application Dim PPPres As PowerPoint. Presentation Dim PPSlide As PowerPoint. SlideDim i As Integer Shee…...
Linux字符驱动设备开发入门之框架搭建
声明 本博客所记录的关于正点原子i.MX6ULL开发板的学习笔记,(内容参照正点原子I.MX6U嵌入式linux驱动开发指南,可在正点原子官方获取正点原子Linux开发板 — 正点原子资料下载中心 1.0.0 文档),旨在如实记录我在学校学…...
Nextjs15 实战 - React Notes之SidebarNoteList优化和Suspense的使用
current branch 对应如下文档 redis ioredis 本专栏内容均可在Github:notes_02 找到 完整项目使用技术栈: Nextjs15 MySQL Redis Auth Prisma i18n strapi Docker vercel 一、本节目标 实现笔记列表展开回收和 Suspense 的实践 二、修改根…...
第三十章:Python-NetworkX库:创建、操作与研究复杂网络
一、NetworkX库简介 NetworkX是一个强大的Python库,用于创建、操作和研究复杂网络(图)的结构、动态和功能。它支持多种类型的图,包括无向图、有向图、加权图和多重图,并提供了丰富的图论算法和可视化工具。资源绑定附…...
cpp自学 day19(多态)
一、基本概念 同一操作作用于不同的对象,产生不同的执行结果 👉 就像「按F1键」:在Word弹出帮助文档,在PS弹出画笔设置,同一个按键触发不同功能 (1)多态类型 类型实现方式绑定时机静态多态…...
Unity:销毁(Destroy)
Destroy的基本概念 Destroy是Unity提供的一个方法,用于立即或延迟销毁游戏对象(GameObject)或其组件(Component)。它会从场景中移除对象,并释放相关资源(比如内存)。 语法 销毁Ga…...
【C++初阶】模板进阶
目录 模板参数 模板的特化 函数特化 类模板特化 全特化 偏特化 模板分离编译 分离编译 模板的分离编译 为什么模板不支持声明和定义分离呢? 解决方法 模板总结 优点 缺点 模板参数 模板参数分为类型形参和非类型参数 类型形参:出现在模板…...
BN 层的作用, 为什么有这个作用?
BN 层(Batch Normalization)——这是深度神经网络中非常重要的一环,它大大改善了网络的训练速度、稳定性和收敛效果。 🧠 一句话理解 BN 层的作用: Batch Normalization(批归一化)通过标准化每一…...
CNN 里面能自然起到防止过拟合的办法
在 CNN(卷积神经网络)中,其实有 一些结构和机制 天然就具有防止过拟合(overfitting)的作用,不完全依赖额外的正则化手段。 🧠 一、CNN 天然防过拟合的几个原因: 1️⃣ 局部连接&…...
存储基石:深度解读Linux磁盘管理机制与文件系统实战
Linux系列 文章目录 Linux系列前言一、磁盘1.1 初识磁盘1.2 磁盘的物理结构1.3 磁盘的存储结构1.4 磁盘的逻辑结构 二、文件系统2.1 系统对磁盘的管理2.2 文件在磁盘中的操作 前言 Linux 文件系统是操作系统中用于管理和组织存储设备(如硬盘、SSD、USB 等ÿ…...
AI Agent设计模式六:ReAct
概念 :思考-执行循环系统 ✅ 优点:提升任务完成度,适合复杂问题拆解❌ 缺点:执行延迟较高,资源消耗大 from langchain_core.messages import SystemMessage, HumanMessage, ToolMessage, AIMessage from langgraph.pr…...
使用MySQL时出现 Ignoring query to other database 错误
Ignoring query to other database 错误 当在远程连接软件中输入MySQL命令出现该错误 导致错误原因是:登录mysql时账户名没有加上u 如果出现该错误,退出mysql,重新输入正确格式进入即可!...
(三)链式工作流构建——打造智能对话的强大引擎
上一篇:(二)输入输出处理——打造智能对话的灵魂 在前两个阶段,我们已经搭建了一个基础的智能对话,并深入探讨了输入输出处理的细节。今天,我们将进入智能对话的高级阶段——链式工作流构建。这一阶段的目…...