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 修饰符。

相关推荐
weixin_4493108416 分钟前
高效集成:聚水潭采购数据同步到MySQL
android·数据库·mysql
Zender Han31 分钟前
Flutter自定义矩形进度条实现详解
android·flutter·ios
白乐天_n2 小时前
adb:Android调试桥
android·adb
姑苏风6 小时前
《Kotlin实战》-附录
android·开发语言·kotlin
数据猎手小k10 小时前
AndroidLab:一个系统化的Android代理框架,包含操作环境和可复现的基准测试,支持大型语言模型和多模态模型。
android·人工智能·机器学习·语言模型
你的小1010 小时前
JavaWeb项目-----博客系统
android
风和先行11 小时前
adb 命令查看设备存储占用情况
android·adb
AaVictory.12 小时前
Android 开发 Java中 list实现 按照时间格式 yyyy-MM-dd HH:mm 顺序
android·java·list
似霰13 小时前
安卓智能指针sp、wp、RefBase浅析
android·c++·binder
大风起兮云飞扬丶13 小时前
Android——网络请求
android