一、基础认知(必懂)
- 链式调用 (Chaining) :通过点号
. 连接多个修饰符(比如先设尺寸再设背景,背景会适配尺寸;反之则尺寸覆盖背景);
Text(
text = "Hello",
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(8.dp)
.background(Color.White)
.border(1.dp, Color.Gray)
.clip(RoundedCornerShape(4.dp))
.clickable { }
.enabled(true)
)
建议:先写布局,再写样式,最后写交互;
-
顺序敏感 (Order Matters) :这是新手最容易踩坑的地方。Modifier 的执行顺序是从左到右的,前一个修饰符的结果会影响后一个修饰符。
- 错误示例:先
.clickable() 再 .padding()。点击区域只包含内容本身,不包含内边距区域。
- 正确示例:先
.padding() 再 .clickable()。点击区域包含内边距,用户体验更好。
- 绘制顺序:
background 如果在 padding 之前,背景色会填充整个包括 padding 的区域;如果在之后,背景色只包裹内容。
-
不可变性 (Immutability) :每次调用修饰符函数都会返回一个新的 Modifier 对象,不会修改原对象。
二、九大类内置用法(详细版)
1. 尺寸控制(最基础,100% 高频)
| 用法 | 核心作用 | 关键参数 | 示例 | 适用场景 |
|---|
size(dp) | 同时设置宽高为固定值 | size: Dp | Modifier.size(100.dp) | 固定尺寸的组件(如按钮、图片) |
size(width, height) | 分别设置宽 / 高 | width: Dp, height: Dp | Modifier.size(200.dp, 150.dp) | 非正方形组件 |
width(dp) | 单独设置宽度 | width: Dp | Modifier.width(300.dp) | 宽度固定、高度自适应 |
height(dp) | 单独设置高度 | height: Dp | Modifier.height(50.dp) | 高度固定、宽度自适应 |
fillMaxSize(fraction) | 占满父容器宽高(可选比例) | fraction: Float = 1f | Modifier.fillMaxSize(0.8f) | 全屏 / 占父容器比例的组件(如页面容器) |
fillMaxWidth(fraction) | 占满父容器宽度 | fraction: Float = 1f | Modifier.fillMaxWidth() | 宽度撑满、高度自适应(如输入框) |
fillMaxHeight(fraction) | 占满父容器高度 | fraction: Float = 1f | Modifier.fillMaxHeight(0.5f) | 高度撑满、宽度自适应(如侧边栏) |
wrapContentSize(align) | 宽高包裹内容(可选对齐) | align: Alignment = Alignment.Center | Modifier.wrapContentSize(Alignment.TopStart) | 内容不确定的组件(如动态文本) |
minSize(width, height) | 设置最小宽高 | minWidth: Dp, minHeight: Dp | Modifier.minSize(50.dp, 30.dp) | 防止组件过小(如按钮) |
maxSize(width, height) | 设置最大宽高 | maxWidth: Dp, maxHeight: Dp | Modifier.maxSize(200.dp) | 防止组件过大(如图片) |
requiredSize(dp) | 强制设置尺寸(忽略父约束) | size: Dp | Modifier.requiredSize(300.dp) | 必须固定尺寸,不受父容器限制 |
2. 布局与间距(90% 高频)
| 用法 | 核心作用 | 关键参数 | 示例 | 适用场景 |
|---|
padding(all) | 全方向内边距 | all: Dp | Modifier.padding(16.dp) | 组件内容与边框的间距 |
padding(horizontal/vertical) | 分方向内边距 | horizontal: Dp, vertical: Dp | Modifier.padding(horizontal = 16.dp, vertical = 8.dp) | 水平 / 垂直间距不同的场景 |
padding(start/top/end/bottom) | 精准设置单方向内边距 | start: Dp, top: Dp, end: Dp, bottom: Dp | Modifier.padding(top = 8.dp, start = 12.dp) | 自定义单边间距(如文本靠左) |
paddingFromBaseline(top/bottom) | 基于文本基线的内边距 | top: Dp, bottom: Dp | Modifier.paddingFromBaseline(top = 24.dp) | 文字排版对齐(如 TextField 提示文字) |
margin() | 无原生 margin!用父容器 padding 模拟 | - | 父 Column 加 padding(8.dp)实现子组件 margin | 组件之间的外边距 |
offset(x, y) | 相对自身位置偏移 | x: Dp, y: Dp | Modifier.offset(x = 10.dp, y = -5.dp) | 微调组件位置(如小红点偏移) |
align(alignment) | 组件在父容器中的对齐 | alignment: Alignment | Modifier.align(Alignment.Center) | 仅在 Row/Column/Box 内生效(子组件对齐) |
weight(fraction, fill) | 占父容器剩余空间比例 | weight: Float, fill: Boolean = true | Modifier.weight(0.6f) | 仅 Row/Column 生效(如分栏布局) |
aspectRatio(ratio) | 设置宽高比 | ratio: Float, matchHeightConstraintsFirst: Boolean = false | Modifier.aspectRatio(16/9f) | 图片 / 视频等比例展示(如横幅、封面) |
3. 视觉样式(80% 高频)
| 用法 | 核心作用 | 关键参数 | 示例 | 适用场景 |
|---|
background(color, shape) | 设置背景色 + 形状 | color: Color, shape: Shape = RectangleShape | Modifier.background(Color.Red, RoundedCornerShape(8.dp)) | 所有组件的背景(按钮、卡片、文本) |
border(width, color, shape) | 设置边框 | width: Dp, color: Color, shape: Shape = RectangleShape | Modifier.border(2.dp, Color.Black, CircleShape) | 带边框的组件(输入框、圆形图片) |
clip(shape) | 裁剪组件为指定形状 | shape: Shape | Modifier.clip(CircleShape) | 圆形图片、圆角卡片 |
alpha(alpha) | 设置透明度 | alpha: Float (0-1) | Modifier.alpha(0.5f) | 禁用状态、遮罩效果 |
shadow(elevation, shape, clip) | 添加阴影 | elevation: Dp, shape: Shape, clip: Boolean = true | Modifier.shadow(4.dp, RoundedCornerShape(8.dp)) | 卡片、按钮的立体效果 |
colorFilter(filter) | 颜色滤镜(改色 / 滤镜) | colorFilter: ColorFilter? | Modifier.colorFilter(ColorFilter.tint(Color.Red)) | 图片改色(如图标 tint) |
rotate(degrees) | 旋转组件 | degrees: Float | Modifier.rotate(45f) | 旋转图标、倾斜文本 |
scale(x, y) | 缩放组件 | scaleX: Float, scaleY: Float | Modifier.scale(1.2f) | 点击放大、hover 效果 |
blur(radius) | 模糊效果 | radius: Dp | Modifier.blur(4.dp) | 毛玻璃、加载遮罩 |
paint(painter) | 自定义绘制背景(图片 / 渐变) | painter: Painter | Modifier.paint(painterResource(R.drawable.bg)) | 图片背景、渐变背景 |
4.交互行为(70% 高频)
| 用法 | 核心作用 | 关键参数 | 示例 | 适用场景 |
|---|
clickable(onClick, enabled) | 添加点击事件 | onClick: () -> Unit, enabled: Boolean = true | Modifier.clickable { println("点击") } | 所有可点击组件(文本、卡片、图片) |
pointerInput(key, block) | 自定义触摸事件 | key: Any?, block: suspend PointerInputScope.() -> Unit | Modifier.pointerInput(Unit) { detectTapGestures(onLongPress = { /* 长按 */ }) } | 长按、双击、滑动等自定义触摸 |
verticalScroll(state) | 开启垂直滚动 | state: ScrollState | Modifier.verticalScroll(rememberScrollState()) | Column 等容器的滚动(少量子项) |
horizontalScroll(state) | 开启水平滚动 | state: ScrollState | Modifier.horizontalScroll(rememberScrollState()) | Row 等容器的滚动(少量子项) |
scrollable(state, orientation) | 可滚动(自定义逻辑) | state: ScrollableState, orientation: Orientation | Modifier.scrollable(scrollState, Orientation.Vertical) | 自定义滚动行为(如滚动条) |
enabled(enabled) | 设置组件是否可用 | enabled: Boolean | Modifier.enabled(false) | 按钮、输入框的禁用状态 |
selectable(selected, onSelect) | 可选中(单选) | selected: Boolean, onSelect: () -> Unit | Modifier.selectable(selected = true, onSelect = {}) | 单选按钮、Tab 切换 |
selectableGroup() | 标记单选组 | - | Modifier.selectableGroup() | 多个 selectable 组成单选组 |
draggable(state, orientation) | 可拖拽 | state: DraggableState, orientation: Orientation | Modifier.draggable(dragState, Orientation.Horizontal) | 滑块、拖拽排序 |
swipeable(state, anchors) | 可滑动(如侧滑删除) | state: SwipeableState, anchors: Map<Dp, T> | Modifier.swipeable(swipeState, anchors = mapOf(0.dp to 0, 100.dp to 1)) | 侧滑删除、下拉刷新 |
nestedScroll(connection) | 嵌套滚动 | connection: NestedScrollConnection | Modifier.nestedScroll(connection) | 嵌套滚动布局(如列表内的滚动卡片) |
pointerEvents(mode) | 控制触摸事件响应 | mode: PointerEvents | Modifier.pointerEvents(PointerEvents.None) | 禁用组件的触摸响应(如遮罩层) |
5.布局约束(进阶,30% 高频)
| 用法 | 核心作用 | 关键参数 | 示例 | 适用场景 |
|---|
layout(measure) | 自定义测量 / 放置逻辑 | measure: MeasureScope.(measurable: Measurable, constraints: Constraints) -> MeasureResult | Modifier.layout { measurable, constraints -> /* 自定义测量 */ } | 自定义布局(如流式布局) |
layoutId(id) | 给组件设置唯一 ID | id: Any | Modifier.layoutId("header") | 自定义布局(如 ConstraintLayout) |
wrapContentWidth(align) | 仅宽度包裹内容 | align: Alignment.Horizontal = Alignment.CenterHorizontally | Modifier.wrapContentWidth(Alignment.End) | 宽度自适应、水平对齐 |
wrapContentHeight(align) | 仅高度包裹内容 | align: Alignment.Vertical = Alignment.CenterVertically | Modifier.wrapContentHeight(Alignment.Bottom) | 高度自适应、垂直对齐 |
6.状态与动画(进阶,20% 高频)
| 用法 | 核心作用 | 关键参数 | 示例 | 适用场景 |
|---|
animateContentSize(animationSpec) | 尺寸变化带动画 | animationSpec: AnimationSpec<IntSize> = defaultSpring() | Modifier.animateContentSize() | 动态文本、折叠面板 |
animateEnterExit(enter, exit) | 入场 / 退场动画 | enter: EnterTransition, exit: ExitTransition | Modifier.animateEnterExit(enter = fadeIn(), exit = fadeOut()) | 组件的显示 / 隐藏动画 |
key(key) | 自定义重组键 | key: Any? | Modifier.key(user.id) | 仅当 key 变化时重组组件(列表项) |
stable | 标记修饰符为稳定,减少重组 | - | Modifier.stable | 自定义稳定修饰符(进阶) |
7.无障碍(适配,10% 高频)
| 用法 | 核心作用 | 关键参数 | 示例 | 适用场景 |
|---|
semantics(properties) | 添加无障碍语义 | properties: SemanticsPropertyReceiver.() -> Unit | Modifier.semantics { contentDescription = "关闭按钮" } | 屏幕阅读器适配(按钮、图标) |
clearAndSetSemantics(properties) | 清除原有语义,设置新语义 | properties: SemanticsPropertyReceiver.() -> Unit | Modifier.clearAndSetSemantics { isButton = true } | 覆盖默认语义(如自定义按钮) |
testTag(tag) | 设置测试标签(UI 测试) | tag: String | Modifier.testTag("login_button") | 自动化 UI 测试定位组件 |
8.文本专属(文本组件,50% 高频)
| 用法 | 核心作用 | 关键参数 | 示例 | 适用场景 |
|---|
lineHeight(height) | 设置文本行高 | height: TextUnit | Modifier.lineHeight(24.sp) | 文本排版(多行文本) |
letterSpacing(spacing) | 设置字符间距 | spacing: TextUnit | Modifier.letterSpacing(2.sp) | 标题、特殊文本排版 |
textDecoration(decoration) | 设置文本装饰(下划线 / 删除线) | decoration: TextDecoration | Modifier.textDecoration(TextDecoration.Underline) | 链接、已完成文本 |
9.其他实用用法(补充)
| 用法 | 核心作用 | 示例 | 适用场景 |
|---|
combinedClickable(onClick, onLongClick) | 点击 + 长按 + 双击事件 | Modifier.combinedClickable(onLongClick = { /* 长按 */ }) { /* 点击 */ } | 同时需要点击 / 长按的组件 |
focusable(enabled) | 可获取焦点 | Modifier.focusable(true) | 输入框、键盘导航 |
focusRequester(requester) | 请求焦点 | Modifier.focusRequester(focusRequester) | 自动聚焦输入框 |
imePadding() | 添加软键盘内边距 | Modifier.imePadding() | 输入框避免被软键盘遮挡 |
navigationBarsPadding() | 添加导航栏内边距 | Modifier.navigationBarsPadding() | 底部组件避免被导航栏遮挡 |
statusBarsPadding() | 添加状态栏内边距 | Modifier.statusBarsPadding() | 顶部组件避免被状态栏遮挡 |
三、核心使用规范(避坑关键)
1. 修饰符编写顺序(推荐)
按「布局 → 样式 → 交互」的顺序编写,符合直觉且易维护:
Modifier
.fillMaxWidth()
.height(50.dp)
.padding(8.dp)
.background(Color.White)
.border(1.dp, Color.Gray)
.clip(RoundedCornerShape(4.dp))
.clickable { }
.enabled(true)
2. 常见错误避坑
- ❌ 顺序错误导致效果异常:
Modifier.background(Color.Red).size(100.dp) → 背景会被尺寸裁剪,应先设尺寸再设背景;
- ❌ 冗余修饰符:
Modifier.fillMaxSize().size(100.dp) → size 会覆盖 fillMaxSize,前者无意义;
- ❌ 滚动布局中用
weight:Column(Modifier.verticalScroll(...)) 内的 weight 失效(滚动布局无固定剩余空间);
- ❌ 给非容器组件加
verticalScroll:Text(Modifier.verticalScroll(...)) 无效果,需嵌套 Column。
四、 总结
- 核心分类:Modifier 内置用法可归为 9 大类,日常开发优先掌握「尺寸、布局、样式、交互」4 类(覆盖 90% 场景);
- 执行规则:链式调用从左到右执行,顺序直接影响最终效果;
- 编写规范:按「布局→样式→交互」顺序编写,避免冗余和顺序错误;
- 作用域:部分修饰符仅对特定组件生效(如
weight 仅 Row/Column,verticalScroll 仅容器)。