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

相关推荐
Dovis(誓平步青云)36 分钟前
家里设备越来越多,如何用一张空间地图控制灯光和温度![
android·java·前端·javascript·人工智能·电脑
晚风叙码2 小时前
MySQL 数据类型详解:从数值到字符串,一篇讲透
android·mysql·adb
传奇开心果编程3 小时前
【Compose Multiplatform 跨端开发学与练】第3课 布局与组件
android·windows·学习·ui·ios·kotlin·composer
传奇开心果编程6 小时前
【Compose Multiplatform 跨端开发学与练】第8课 资源管理与主题
android·windows·学习·ios·kotlin·web·composer
传奇开心果编程7 小时前
【Compose Multiplatform 跨端开发学与练】第9课 测试与调试
android·学习·macos·ios·kotlin·web·composer
传奇开心果编程7 小时前
【Compose Multiplatform 跨端开发学与练】第4课 导航与路由
android·windows·学习·ui·ios·kotlin·composer
传奇开心果编程8 小时前
【Compose Multiplatform 跨端开发学与练】第6课 状态管理与架构
android·学习·ui·ios·架构·kotlin·composer
事圆则缓8 小时前
Android AOSP 定制常见概念:源码目录、系统镜像与刷机流程
android
传奇开心果编程8 小时前
【Compose Multiplatform 跨端开发学与练】第2课 Compose 基础语法
android·windows·学习·ui·ios·kotlin·composer
supabc1238 小时前
Celium:连接 Windows、Mac、Linux 与 Android,让远程访问和设备管理更简单
android·linux·windows·macos·远程访问·网络管理·celium