在 Jetpack Compose 中,size、sizeIn、requiredSize、wrapContentSize、padding、fillMaxSize

517 阅读3分钟

1. size:设置固定尺寸

作用:直接指定组件的宽度和高度(或单一维度),覆盖默认的尺寸计算逻辑。
适用场景:需要固定组件大小(如图标、按钮)。

@Composable
fun SizeExample() {
    Box(
        modifier = Modifier
            .size(width = 100.dp, height = 50.dp) // 宽100dp,高50dp
            .background(Color.Blue)
    ) {
        Text(
            text = "Fixed Size",
            color = Color.White,
            modifier = Modifier.align(Alignment.Center)
        )
    }
}

2. sizeIn:限定尺寸范围

作用:设置组件的最小 / 最大宽度和高度,确保尺寸在指定范围内(内容自适应时不会过小或过大)。
适用场景:需要组件根据内容调整大小,但限制其极值(如输入框、卡片)。

@Composable
fun SizeInExample() {
    Text(
        text = "Long long long text content", // 内容较长
        modifier = Modifier
            .sizeIn(
                minWidth = 80.dp,   // 最小宽度
                maxWidth = 200.dp,  // 最大宽度
                minHeight = 40.dp,  // 最小高度
                maxHeight = 100.dp  // 最大高度
            )
            .background(Color.LightGray)
            .padding(8.dp)
    )

3. requiredSize:强制固定尺寸

作用:强制组件尺寸为指定值,忽略内容本身的大小(可能导致内容溢出或空白)。
适用场景:需要严格控制组件尺寸(如固定大小的容器)。

@Composable
fun RequiredSizeExample() {
    Text(
        text = "Small Text", // 内容较小
        modifier = Modifier
            .requiredSize(150.dp) // 强制宽高为150dp
            .background(Color.Green)
            .padding(8.dp)
    )
    // 效果:文本周围会有大量空白(内容尺寸 < requiredSize)
}

4. wrapContentSize:内容包裹尺寸

作用:让组件根据内容自动调整尺寸(默认尽可能小),可通过 Alignment 控制内容在可用空间内的位置。
适用场景:需要组件紧密包裹内容(如提示气泡、图标)。

@Composable
fun WrapContentSizeExample() {
    Box(
        modifier = Modifier
            .background(Color.Yellow)
            .wrapContentSize(Alignment.Center) // 内容居中,组件尺寸包裹内容
    ) {
        Text(
            text = "Wrap Content",
            modifier = Modifier.padding(12.dp)
        )
    }
}

5. padding:内边距

作用:在组件内部内容与边界之间添加空间,优化视觉间距。

适用场景:所有需要调整内容与边界距离的场景(如文本、按钮)。

说明:在compose中没有了margin,根据Modifier的顺序来处理边距padding是否可以被点击到。

@Composable
fun PaddingExample() {
    Text(
        text = "Text with Padding",
        modifier = Modifier
            .background(Color.Purple)
            .padding(
                horizontal = 16.dp, // 左右内边距16dp
                vertical = 8.dp     // 上下内边距8dp
            )
    )
}
@Composable
fun ArtistCard(/*...*/) {
    val padding = 16.dp
    Column(
        Modifier
            .clickable(onClick = onClick)
            .padding(padding)
            .fillMaxWidth()
    ) {
        // rest of the implementation
    }
}

在上面的代码中,整个区域(包括周围的内边距)都是可点击的,因为 padding 修饰符应用在 clickable 修饰符后面。**如果修饰符顺序相反,由 padding 添加的空间就不会响应用户输入:

@Composable
fun ArtistCard(/*...*/) {
    val padding = 16.dp
    Column(
        Modifier
            .padding(padding)
            .clickable(onClick = onClick)
            .fillMaxWidth()
    ) {
        // rest of the implementation
    }
}

6. fillMaxSize:填充父容器

作用:让组件扩展以填充父容器的可用空间(可设置比例,默认填满)。
适用场景:需要组件占满父容器(如背景、全屏加载页)。

@Composable
fun FillMaxSizeExample() {
    Box(
        modifier = Modifier
            .fillMaxSize(0.8f) // 填充父容器的80%宽高
            .background(Color.Orange)
    ) {
        Text(
            text = "Fill 80% of Parent",
            modifier = Modifier.align(Alignment.Center)
        )
    }
}

7. 运行的最终界面

image.png

8. 代码

@Composable
fun LayoutModifiersDemo() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp)
    ) {
        // size 示例
        Text("1. size(固定尺寸):")
        Box(
            modifier = Modifier
                .size(width = 100.dp, height = 50.dp)
                .background(Color.Blue)
        ) {
            Text(
                "Fixed Size",
                color = Color.White,
                modifier = Modifier.align(Alignment.Center)
            )
        }

        Spacer(modifier = Modifier.height(20.dp))

        // sizeIn 示例
        Text("2. sizeIn(尺寸范围):")
        Text(
            "Long long long text content",
            modifier = Modifier
                .sizeIn(minWidth = 80.dp, maxWidth = 200.dp, minHeight = 40.dp, maxHeight = 100.dp)
                .background(Color.LightGray)
                .padding(8.dp)
        )

        Spacer(modifier = Modifier.height(20.dp))

        // requiredSize 示例
        Text("3. requiredSize(强制尺寸):")
        Text(
            "Small Text",
            modifier = Modifier
                .requiredSize(150.dp)
                .background(Color.Green)
                .padding(8.dp)
        )

        Spacer(modifier = Modifier.height(20.dp))

        // wrapContentSize 示例
        Text("4. wrapContentSize(内容包裹):")
        Box(
            modifier = Modifier
                .background(Color.Yellow)
                .wrapContentSize(Alignment.Center)
        ) {
            Text("Wrap Content", modifier = Modifier.padding(12.dp))
        }

        Spacer(modifier = Modifier.height(20.dp))

        // padding 示例
        Text("5. padding(内边距):")
        Text(
            "Text with Padding",
            modifier = Modifier
                .background(Color.Blue)
                .padding(horizontal = 16.dp, vertical = 8.dp)
        )

        Spacer(modifier = Modifier.height(20.dp))

        // fillMaxSize 示例
        Text("6. fillMaxSize(填充父容器):")
        Box(
            modifier = Modifier
                .fillMaxSize(0.8f)
                .background(Color.LightGray)
        ) {
            Text(
                "Fill 80% of Parent",
                modifier = Modifier.align(Alignment.Center)
            )
        }
    }
}

9.说明

fillMaxSize: 与xml布局的 match_parent (fill_parent) 相对应

matchParentSize 仅在 Box 作用域内可用,这意味着它仅适用于 Box 可组合项的直接子项

@Composable
fun MatchParentSizeComposable() {
    Box {
        Spacer(
            Modifier
                .matchParentSize()
                .background(Color.LightGray)
        )
        ArtistCard()
    }
}

如果使用 fillMaxSize 代替 matchParentSizeSpacer 将占用父项允许的所有可用空间,反过来使父项展开并填满所有可用空间。

以下是二个效果图:

matchParentSize

image.png

fillMaxSize

image.png

上面二张图来自官网:developer.android.google.cn/develop/ui/…

wrapContentSize: 与xml中布局中的wrap_content相对应

requiredSize: 希望可组合项的尺寸固定不变,而不考虑传入的约束条件,请使用 requiredSize 修饰符

@Composable
fun ArtistCard(/*...*/) {
    Row(
        modifier = Modifier.size(width = 400.dp, height = 100.dp)
    ) {
        Image(
            /*...*/
            modifier = Modifier.requiredSize(150.dp)
        )
        Column { /*...*/ }
    }
}