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:

.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的方式添加,如下:

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

使用:

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,两种写法是等价的:

//1
Modifier.offset(x = 100.dp, y = 100.dp)
//2
Modifier.offset {IntOffset(100.dp.roundToPx(), 100.dp.roundToPx())}

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

//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,则会被设置为父组件所允许的最大尺寸。示例如下:

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

执行结果:

matchParentSize

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

在这里插入图片描述

weight(作用于Column 和 Row 中)

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

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

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

注意修饰符顺序

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

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

  • 17
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_小马快跑_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值