Compose 内置的 Modifier 用法总结

17 阅读8分钟

一、基础认知(必懂)

  1. 链式调用 (Chaining) :通过点号 . 连接多个修饰符(比如先设尺寸再设背景,背景会适配尺寸;反之则尺寸覆盖背景);
Text(
    text = "Hello",
    modifier = Modifier
     // 1. 布局(尺寸、间距、对齐)
     .fillMaxWidth()
     .height(50.dp)
     .padding(8.dp)
     // 2. 样式(背景、边框、裁剪)
    .background(Color.White)
    .border(1.dp, Color.Gray)
    .clip(RoundedCornerShape(4.dp))
    // 3. 交互(点击、滚动、禁用)
    .clickable { /* 点击 */ }
    .enabled(true)
)

建议:先写布局,再写样式,最后写交互;

  1. 顺序敏感 (Order Matters)这是新手最容易踩坑的地方Modifier 的执行顺序是从左到右的,前一个修饰符的结果会影响后一个修饰符。

    • 错误示例:先 .clickable() 再 .padding()。点击区域只包含内容本身,不包含内边距区域。
    • 正确示例:先 .padding() 再 .clickable()。点击区域包含内边距,用户体验更好。
    • 绘制顺序background 如果在 padding 之前,背景色会填充整个包括 padding 的区域;如果在之后,背景色只包裹内容。
  2. 不可变性 (Immutability) :每次调用修饰符函数都会返回一个新的 Modifier 对象,不会修改原对象。

二、九大类内置用法(详细版)

1. 尺寸控制(最基础,100% 高频)

用法核心作用关键参数示例适用场景
size(dp)同时设置宽高为固定值size: DpModifier.size(100.dp)固定尺寸的组件(如按钮、图片)
size(width, height)分别设置宽 / 高width: Dp, height: DpModifier.size(200.dp, 150.dp)非正方形组件
width(dp)单独设置宽度width: DpModifier.width(300.dp)宽度固定、高度自适应
height(dp)单独设置高度height: DpModifier.height(50.dp)高度固定、宽度自适应
fillMaxSize(fraction)占满父容器宽高(可选比例)fraction: Float = 1fModifier.fillMaxSize(0.8f)全屏 / 占父容器比例的组件(如页面容器)
fillMaxWidth(fraction)占满父容器宽度fraction: Float = 1fModifier.fillMaxWidth()宽度撑满、高度自适应(如输入框)
fillMaxHeight(fraction)占满父容器高度fraction: Float = 1fModifier.fillMaxHeight(0.5f)高度撑满、宽度自适应(如侧边栏)
wrapContentSize(align)宽高包裹内容(可选对齐)align: Alignment = Alignment.CenterModifier.wrapContentSize(Alignment.TopStart)内容不确定的组件(如动态文本)
minSize(width, height)设置最小宽高minWidth: Dp, minHeight: DpModifier.minSize(50.dp, 30.dp)防止组件过小(如按钮)
maxSize(width, height)设置最大宽高maxWidth: Dp, maxHeight: DpModifier.maxSize(200.dp)防止组件过大(如图片)
requiredSize(dp)强制设置尺寸(忽略父约束)size: DpModifier.requiredSize(300.dp)必须固定尺寸,不受父容器限制

2. 布局与间距(90% 高频)

用法核心作用关键参数示例适用场景
padding(all)全方向内边距all: DpModifier.padding(16.dp)组件内容与边框的间距
padding(horizontal/vertical)分方向内边距horizontal: Dp, vertical: DpModifier.padding(horizontal = 16.dp, vertical = 8.dp)水平 / 垂直间距不同的场景
padding(start/top/end/bottom)精准设置单方向内边距start: Dp, top: Dp, end: Dp, bottom: DpModifier.padding(top = 8.dp, start = 12.dp)自定义单边间距(如文本靠左)
paddingFromBaseline(top/bottom)基于文本基线的内边距top: Dp, bottom: DpModifier.paddingFromBaseline(top = 24.dp)文字排版对齐(如 TextField 提示文字)
margin()无原生 margin!用父容器 padding 模拟-父 Column 加 padding(8.dp)实现子组件 margin组件之间的外边距
offset(x, y)相对自身位置偏移x: Dp, y: DpModifier.offset(x = 10.dp, y = -5.dp)微调组件位置(如小红点偏移)
align(alignment)组件在父容器中的对齐alignment: AlignmentModifier.align(Alignment.Center)仅在 Row/Column/Box 内生效(子组件对齐)
weight(fraction, fill)占父容器剩余空间比例weight: Float, fill: Boolean = trueModifier.weight(0.6f)仅 Row/Column 生效(如分栏布局)
aspectRatio(ratio)设置宽高比ratio: Float, matchHeightConstraintsFirst: Boolean = falseModifier.aspectRatio(16/9f)图片 / 视频等比例展示(如横幅、封面)

3. 视觉样式(80% 高频)

用法核心作用关键参数示例适用场景
background(color, shape)设置背景色 + 形状color: Color, shape: Shape = RectangleShapeModifier.background(Color.Red, RoundedCornerShape(8.dp))所有组件的背景(按钮、卡片、文本)
border(width, color, shape)设置边框width: Dp, color: Color, shape: Shape = RectangleShapeModifier.border(2.dp, Color.Black, CircleShape)带边框的组件(输入框、圆形图片)
clip(shape)裁剪组件为指定形状shape: ShapeModifier.clip(CircleShape)圆形图片、圆角卡片
alpha(alpha)设置透明度alpha: Float (0-1)Modifier.alpha(0.5f)禁用状态、遮罩效果
shadow(elevation, shape, clip)添加阴影elevation: Dp, shape: Shape, clip: Boolean = trueModifier.shadow(4.dp, RoundedCornerShape(8.dp))卡片、按钮的立体效果
colorFilter(filter)颜色滤镜(改色 / 滤镜)colorFilter: ColorFilter?Modifier.colorFilter(ColorFilter.tint(Color.Red))图片改色(如图标 tint)
rotate(degrees)旋转组件degrees: FloatModifier.rotate(45f)旋转图标、倾斜文本
scale(x, y)缩放组件scaleX: Float, scaleY: FloatModifier.scale(1.2f)点击放大、hover 效果
blur(radius)模糊效果radius: DpModifier.blur(4.dp)毛玻璃、加载遮罩
paint(painter)自定义绘制背景(图片 / 渐变)painter: PainterModifier.paint(painterResource(R.drawable.bg))图片背景、渐变背景

4.交互行为(70% 高频)

用法核心作用关键参数示例适用场景
clickable(onClick, enabled)添加点击事件onClick: () -> Unit, enabled: Boolean = trueModifier.clickable { println("点击") }所有可点击组件(文本、卡片、图片)
pointerInput(key, block)自定义触摸事件key: Any?, block: suspend PointerInputScope.() -> UnitModifier.pointerInput(Unit) { detectTapGestures(onLongPress = { /* 长按 */ }) }长按、双击、滑动等自定义触摸
verticalScroll(state)开启垂直滚动state: ScrollStateModifier.verticalScroll(rememberScrollState())Column 等容器的滚动(少量子项)
horizontalScroll(state)开启水平滚动state: ScrollStateModifier.horizontalScroll(rememberScrollState())Row 等容器的滚动(少量子项)
scrollable(state, orientation)可滚动(自定义逻辑)state: ScrollableState, orientation: OrientationModifier.scrollable(scrollState, Orientation.Vertical)自定义滚动行为(如滚动条)
enabled(enabled)设置组件是否可用enabled: BooleanModifier.enabled(false)按钮、输入框的禁用状态
selectable(selected, onSelect)可选中(单选)selected: Boolean, onSelect: () -> UnitModifier.selectable(selected = true, onSelect = {})单选按钮、Tab 切换
selectableGroup()标记单选组-Modifier.selectableGroup()多个 selectable 组成单选组
draggable(state, orientation)可拖拽state: DraggableState, orientation: OrientationModifier.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: NestedScrollConnectionModifier.nestedScroll(connection)嵌套滚动布局(如列表内的滚动卡片)
pointerEvents(mode)控制触摸事件响应mode: PointerEventsModifier.pointerEvents(PointerEvents.None)禁用组件的触摸响应(如遮罩层)

5.布局约束(进阶,30% 高频)

用法核心作用关键参数示例适用场景
layout(measure)自定义测量 / 放置逻辑measure: MeasureScope.(measurable: Measurable, constraints: Constraints) -> MeasureResultModifier.layout { measurable, constraints -> /* 自定义测量 */ }自定义布局(如流式布局)
layoutId(id)给组件设置唯一 IDid: AnyModifier.layoutId("header")自定义布局(如 ConstraintLayout)
wrapContentWidth(align)仅宽度包裹内容align: Alignment.Horizontal = Alignment.CenterHorizontallyModifier.wrapContentWidth(Alignment.End)宽度自适应、水平对齐
wrapContentHeight(align)仅高度包裹内容align: Alignment.Vertical = Alignment.CenterVerticallyModifier.wrapContentHeight(Alignment.Bottom)高度自适应、垂直对齐

6.状态与动画(进阶,20% 高频)

用法核心作用关键参数示例适用场景
animateContentSize(animationSpec)尺寸变化带动画animationSpec: AnimationSpec<IntSize> = defaultSpring()Modifier.animateContentSize()动态文本、折叠面板
animateEnterExit(enter, exit)入场 / 退场动画enter: EnterTransition, exit: ExitTransitionModifier.animateEnterExit(enter = fadeIn(), exit = fadeOut())组件的显示 / 隐藏动画
key(key)自定义重组键key: Any?Modifier.key(user.id)仅当 key 变化时重组组件(列表项)
stable标记修饰符为稳定,减少重组-Modifier.stable自定义稳定修饰符(进阶)

7.无障碍(适配,10% 高频)

用法核心作用关键参数示例适用场景
semantics(properties)添加无障碍语义properties: SemanticsPropertyReceiver.() -> UnitModifier.semantics { contentDescription = "关闭按钮" }屏幕阅读器适配(按钮、图标)
clearAndSetSemantics(properties)清除原有语义,设置新语义properties: SemanticsPropertyReceiver.() -> UnitModifier.clearAndSetSemantics { isButton = true }覆盖默认语义(如自定义按钮)
testTag(tag)设置测试标签(UI 测试)tag: StringModifier.testTag("login_button")自动化 UI 测试定位组件

8.文本专属(文本组件,50% 高频)

用法核心作用关键参数示例适用场景
lineHeight(height)设置文本行高height: TextUnitModifier.lineHeight(24.sp)文本排版(多行文本)
letterSpacing(spacing)设置字符间距spacing: TextUnitModifier.letterSpacing(2.sp)标题、特殊文本排版
textDecoration(decoration)设置文本装饰(下划线 / 删除线)decoration: TextDecorationModifier.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
// 1. 布局(尺寸、间距、对齐)
.fillMaxWidth()
.height(50.dp)
.padding(8.dp)
// 2. 样式(背景、边框、裁剪)
.background(Color.White)
.border(1.dp, Color.Gray)
.clip(RoundedCornerShape(4.dp))
// 3. 交互(点击、滚动、禁用)
.clickable { /* 点击 */ }
.enabled(true)

2. 常见错误避坑

  • ❌ 顺序错误导致效果异常:Modifier.background(Color.Red).size(100.dp) → 背景会被尺寸裁剪,应先设尺寸再设背景;
  • ❌ 冗余修饰符:Modifier.fillMaxSize().size(100.dp) → size 会覆盖 fillMaxSize,前者无意义;
  • ❌ 滚动布局中用 weightColumn(Modifier.verticalScroll(...)) 内的 weight 失效(滚动布局无固定剩余空间);
  • ❌ 给非容器组件加 verticalScrollText(Modifier.verticalScroll(...)) 无效果,需嵌套 Column。

四、 总结

  1. 核心分类:Modifier 内置用法可归为 9 大类,日常开发优先掌握「尺寸、布局、样式、交互」4 类(覆盖 90% 场景);
  2. 执行规则:链式调用从左到右执行,顺序直接影响最终效果;
  3. 编写规范:按「布局→样式→交互」顺序编写,避免冗余和顺序错误;
  4. 作用域:部分修饰符仅对特定组件生效(如 weight 仅 Row/Column,verticalScroll 仅容器)。