Jetpack Compose | Modifier常用修饰符的使用(一)

Modifier修饰符

Compose提供了Column、Row、Box 三种布局组件,其中Column/Row 对应 View体系中LinearLayout的 Vertical/Horizontal 方向,Box相当于 FrameLayout,而借助Modifier修饰符,可以修饰或扩充布局组件。通常使用修饰符来执行以下操作:

  • 更改可组合项的大小、布局、行为和外观
  • 添加信息,如无障碍标签
  • 处理用户输入
  • 添加高级互动,如使元素可点击、可滚动、可拖动或可缩放

Modifier 以链式调用的方式来设置组件的样式,每个UI 组件都会有一个modifier参数,通过传入该参数来改变组件。

常用修饰符

列举一些常用的Modifier 修饰符:

  • Modifier.width(width: Dp)
  • Modifier.height(height: Dp)
  • Modifier.size(width: Dp, height: Dp)

设置具体的宽高,单位是dp, 如设置宽度500dp,高度100dp:

kotlin 复制代码
.width(500.dp).height(100.dp)
//或者直接在size里设置宽高
//.size(width = 500.dp, height = 100.dp)

如果子布局中有 requiredSize,那么requiredSize的优先级更高一些,如果希望尺寸固定不变,而不考虑传入的约束条件,请使用 requiredSize 修饰符。

  • Modifier.fillMaxWidth(fraction: Float = 1f) :子布局填充父项允许的所有可用宽度
  • Modifier.fillMaxHeight(fraction: Float = 1f) :子布局填充父项允许的所有可用高度
  • Modifier.fillMaxSize(fraction: Float = 1f) :子布局填充父项允许的所有可用宽高

让内容填充(可能仅部分填充)传入的测量约束的最大宽高,其中fraction 取值范围是0.0, 1.0,默认是1.0。

  • Modifier.background(color: Color, shape: Shape = RectangleShape)

设置背景,如果想设置渐变色的背景,可以通过Brush的方式添加,如下:

kotlin 复制代码
 Modifier.background(brush: Brush,
         shape: Shape = RectangleShape,
         /*@FloatRange(from = 0.0, to = 1.0)*/
         alpha: Float = 1.0f
) 

使用:

kotlin 复制代码
val bgGradient = Brush.verticalGradient(
      colors = listOf(Color.Red, Color.Green, Color.Yellow, Color.Cyan))
//设置渐变色
Row(modifier = Modifier.background(bgGradient)){
   ...
}
  • Modifier.border(border: BorderStroke, shape: Shape)
  • Modifier.border(width: Dp, color: Color, shape: Shape)
  • Modifier.border(width: Dp, brush: Brush, shape: Shape)

修改元素,指定外观的边框 ,边框可以指定颜色、粗细、Shape形状等,并进行裁剪。

  • Modifier.padding(all: Dp)
  • Modifier.padding(horizontal: Dp, vertical: Dp)
  • Modifier.padding(start: Dp, top: Dp, end: Dp, bottom: Dp)

设置内外边距,传统的View 体系中有padding和margin的区分,而在Compose中只有一个padding修饰符,根据不同的位置可以表示内、外边距。可以简单理解为:padding在元素的"外部"应用外边距,而在元素的"内部"应用内边距。

  • Modifier.offset(x: Dp = 0.dp, y: Dp = 0.dp)

offset 用来偏移内容,可以直接传入x y,单位是dp,也可以使用offset的重载方法,返回一个IntOffset,两种写法是等价的:

kotlin 复制代码
//1
Modifier.offset(x = 100.dp, y = 100.dp)
//2
Modifier.offset {IntOffset(100.dp.roundToPx(), 100.dp.roundToPx())}

offset 可以是正数,也可以是负数。offset 修饰符根据布局方向水平应用。从左到右布局时,右移为正;反之从右到左布局时,左移为正。如果不考虑布局方向,可以使用 absoluteOffset 修饰符,不管如何布局,会强制向右布局。

kotlin 复制代码
//3 absoluteOffset强制从左向右移动
Modifier.absoluteOffset(x = 100.dp, y = 100.dp)
//4
Modifier.absoluteOffset {IntOffset(100.dp.roundToPx(), 100.dp.roundToPx())}
  • Modifier.align(alignment: Alignment) :在Box的子控件中使用,表示将内容拉取到Box中的特定Alignment位置。Alignment 的取值有:TopStart、TopCenter、TopEnd、CenterStart、Center、CenterEnd、BottomStart、BottomCenter、BottomEnd
  • Modifier.align(alignment: Alignment.Vertical) :在Row的子控件中使用,表示在Row 中垂直对齐元素。Alignment.Vertical 的取值有:Top、CenterVertically、Bottom
  • Modifier.align(alignment: Alignment.Horizontal) :在Column 的子控件中使用,表示在Column 中水平对齐元素。Alignment.Horizontal 的取值有:Start、CenterHorizontally、End

更多Modifier修饰符的用法参见:Modifier修饰符列表:https://developer.android.com/jetpack/compose/modifiers-list?hl=zh-cn

作用域限定

某些Modifier修饰符只能应用于某些可组合项的子项,Compose 通过自定义作用域强制实施此安全机制。

matchParentSize(作用于Box中)

在Box中,如果希望某个子项与父项 Box 同样大,而不影响 Box 尺寸,可以使用 matchParentSize 修饰符。

matchParentSize 仅适用于Box的子控件中,可以保证当前组件的尺寸与父组件相同,父组件如果未设置宽高默认是wrapContent;而如果改为使用fillMaxSize,则会被设置为父组件所允许的最大尺寸。示例如下:

kotlin 复制代码
@Composable
private fun BoxSample() {
   Box {
       Spacer(modifier = Modifier.matchParentSize().background(Color.Yellow))
       Text(text = "Jetpack Compose", modifier = Modifier.padding(10.dp))
    }
}

执行结果:

上述代码中,如果将matchParentSize改为fillMaxSize,则执行结果为:

weight(作用于Column 和 Row 中)

weight只能在Column 和 Row 中使用,跟View体系中LinearLayout中的weight是一个概念。示例如下:

kotlin 复制代码
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.BottomCenter) {
        //设置渐变色
        val bgGradient = Brush.verticalGradient(
            colors = listOf(Color.Red, Color.Green, Color.Yellow, Color.Cyan)
        )
        Row(
            modifier = Modifier
                .background(bgGradient)
                .fillMaxWidth()
                .height(40.dp),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Text(
                text = "Tab1",
                modifier = Modifier.weight(1f), //1
                textAlign = TextAlign.Center,
            )
            Image(
                modifier = Modifier
                    .wrapContentSize(align = Alignment.BottomCenter, true)
                    .weight(1f) //2
                    .clip(CircleShape)
                    .border(width = 2.dp, Color.Red, CircleShape)
                    .requiredSize(80.dp),
                painter = painterResource(id = R.drawable.icon_cat_w),
                contentScale = ContentScale.Crop,
                contentDescription = ""
            )
            Text(
                text = "Tab2",
                modifier = Modifier.weight(1f), //3
                textAlign = TextAlign.Center,
            )
        }
    }

Row中的子控件通过在1、2、3处设置weight 来均分横向宽度,执行结果:

上述示例中是一个综合示例,不仅使用了weight修饰符,还是用的clip、border等,最终展示是三个均分的底部Tab控件,其中图片大小不受父控件的约束(通过requiredSize实现的)。

注意修饰符顺序

修饰符函数的顺序非常重要。因为每个Modifier 修饰符函数都会对上一个函数返回的 Modifier 进行更改,因此顺序会影响最终结果。如:

kotlin 复制代码
Box(
    modifier = Modifier
            .size(200.dp, 100.dp)
            .background(Color.Gray)
            .padding(20.dp)
            .border(1.dp, Color.Red, RectangleShape)
            .padding(20.dp)
            .background(Color.Green)
   )

对于border而言,在其前面的设置padding 可以认为是外边距,在其后面设置的 padding可以认为是内边距。通过修饰符的前后顺序可以控制内外边距,这也说明了为什么没有外边距修饰符,而只有 padding 修饰符。

相关推荐
松仔log10 小时前
Java中级——组合和继承
android·java·开发语言
我命由我1234514 小时前
Jetpack Compose - MaterialExpressiveTheme 与 MaterialTheme、ColorScheme
android·java·开发语言·java-ee·kotlin·android jetpack·android runtime
lilian23315 小时前
Harmony os 技术实战|拼豆制图06:收藏 ID、生成记录与重启恢复怎么不打架
android·java·数据库·harmonyos
2601_9557596215 小时前
ClaudeAPI成本中心与业务标签设计指南
android·java·数据库
余衫马15 小时前
2026最新版!Android Studio 极速安装与配置指南
android·ide·android studio
AFinalStone15 小时前
Android 7系统异常问题排查(五)Framework层(下)—System Server崩溃
android·tombstone·系统异常
AFinalStone15 小时前
Android 7系统异常问题排查(八)系统追踪—Trace机制与性能诊断
android·系统异常
极客猴子19 小时前
Android录音转写频繁卡顿?多款APP长时间会议场景稳定性实测
android·人工智能·智能手机·飞书
Kapaseker19 小时前
Boolean 变量到底该怎么命名?
android·kotlin
AFinalStone19 小时前
Android 7系统异常问题排查(六)应用异常(上)—ANR机制全解
android·系统异常