Android Compose学习 — 修饰符(一) — size

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

概述

通过之前的学习笔记,我们已经简单认识了一些可组合项,并且也了解了一些修饰符的作用。这篇学习笔记是对之前的一个总结,主要是学习和size相关的修饰符的作用。

设置大小

  1. Compose中我们可以通过Modifier.size()指定当前可组合项的大小,如下所示:
    @Composable
    private fun StudySize() {
        Column(modifier = Modifier
            .size(200.dp)
            .background(color = Color.Red)) {
        }
    }
复制代码

上面的代码中指定了Column的大小为200dp,同时设置了一个红色的背景颜色,运行结果如下:

使用size指定大小

  1. 我们可以通过Modifier.size(width,height)来单独对宽度和高度的大小进行指定,如下所示:
    @Composable
    private fun StudySize() {
        Column(modifier = Modifier
            .size(width = 200.dp,height = 100.dp)
            .background(color = Color.Red)) {
        }
    }
复制代码

使用size单独指定宽度和高度

  1. 我们可以通过sizeIn(minWidth,maxWidth,minHeight,maxHeight)方法将可组合项的大小限制到传入的参数中,如下所示:
    @Composable
    private fun StudySize() {
        Column(
            modifier = Modifier
                .sizeIn(
                    minWidth = 100.dp,
                    maxWidth = 200.dp,
                    minHeight = 100.dp,
                    maxHeight = 300.dp
                )
                .background(color = Color.Red)
        ) {
            Text(
                text = "这是测试文本",
                modifier = Modifier
                    .size(50.dp, 200.dp)
                    .background(color = Color.Blue)
            )
        }
    }
复制代码

在上面的代码中,我们指定了Column的最小宽度和最小高度分别为100.dp,最大宽度为200.dp,最大高度为300dp,同时给Column设置了一个子项,他的宽度比Column的最小宽度还小,高度则介于Column的最小高度和最大高度之间,运行效果如下:

使用sizeIn指定最大最小宽度和高度

可以看到,最终子项的宽度在Column内部,而Column的高度则和子项的高度一样了。我们不需要指定全部的参数,可以单独指定某一项的具体大小。

  1. 通过fillMaxSize(fraction: Float)属性设置子可组合项将要占满父组合项可用尺寸的比例,其中的fraction默认值为1,也就是默认占满父组合项的全部可用空间,可以为其设置0 - 1之间的浮点数,从而表示子项占满父项可用尺寸的比例,下面的代码演示了子项占满父项可用空间的一半:
    @Composable
    private fun StudySize() {
        Column(
            modifier = Modifier
                .fillMaxSize(fraction = 0.5f)
                .background(color = Color.Red)
        ) {
            Text(
                text = "这是测试文本",
                modifier = Modifier
                    .size(50.dp, 200.dp)
                    .background(color = Color.Blue)
            )
        }
    }
复制代码

上面的代码运行效果如下:

子项占据父项的比例

  1. 通过defaultMinSize(minWidth,minHeight)可以为可组合项提供默认最小宽度和最小高度,如下所示:
    @Composable
    private fun StudySize() {
        Column(
            modifier = Modifier
                .defaultMinSize(minWidth = 100.dp,minHeight = 300.dp)
                .background(color = Color.Red)
        ) {
        }
    }
复制代码

上面的代码中通过defaultMinSize设置了最小宽度和最小高度,这样即使没有子可组合项也可以看到相应的可组合项,当然,使用size()等属性也可以达到这样的效果,运行效果如下:

defaultSize演示

需要特别注意的是:属性的先后顺序直接影响最终的效果,比如我们修改上面的代码,在使用defaultMinSize()之前使用size(),则会得到如下的效果:

    @Composable
    private fun StudySize() {
        Column(
            modifier = Modifier
                .size(200.dp)
                .defaultMinSize(minWidth = 100.dp,minHeight = 300.dp)
                .background(color = Color.Red)
        ) {
        }
    }
复制代码

属性的先后顺序对绘制效果的影响

可以看到:通过defaultMinSize()指定的参数并没有起作用,而是通过size()指定的参数起了作用。

针对上面的差异,我们现在将size()放在defaultMinSize()的下面,看看最终效果:

    @Composable
    private fun StudySize() {
        Column(
            modifier = Modifier
                .defaultMinSize(minWidth = 100.dp,minHeight = 300.dp)
                .size(200.dp)
                .background(color = Color.Red)
        ) {
        }
    }
复制代码

属性的先后顺序对绘制效果的影响

可以看到,这次两个属性设置的值均起了作用,宽度为300dp,高度为200dp

  1. 通过使用requiredSize(size)可以强制设置可组合项的大小,即使设置的可组合项的大小超过了父项可以提供的大小仍然会按照设置的大小进行绘制。如下所示:
    @Composable
    private fun StudySize() {
        Column(
            modifier = Modifier
                .requiredSize(500.dp)
                .background(color = Color.Red)
        ) {
        }
    }
复制代码

在上面的代码中,我们为可组合项StudySize指定的高度为200dp,但是它自己需要的宽度和高度均为500dp,最终的效果如下:

requiredSize演示

可以看到,子项最终已经完全 覆盖了父项。

  1. 通过使用requiredSize(width,height)可以单独指定宽度和高度的大小,如下所示
    @Composable
    private fun StudySize() {
        Column(
            modifier = Modifier
                .requiredSize(width = 50.dp,height = 300.dp)
                .background(color = Color.Red)
        ) {
        }
    }

复制代码

在上面的代码中,我们指定了Column的宽度为50dp,高度为300dp,它的高度已经超过了其父项的高度,最终效果如下:

明确指定高度和宽度所需的大小

在这里可以看到,在Y轴方向上,子项Column其实是被父项居中放置的。

还需要注意的一点是:当某一个可组合项的大小超过了其父项可以提供的大小,对于其父项而言,和其父项在同一层级的其他的可组合项会受到怎样的影响,下面的代码演示了这种情况:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Box(modifier = Modifier.fillMaxSize()) {
                Column(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.Center) {
                    Text(text = "这是第0个可组合项",modifier = Modifier.fillMaxWidth().height(50.dp).background(color = Color.Magenta))
                    Box(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(200.dp)
                            .background(color = Color(0xFF333333)),
                    ) {
                        StudySize()
                    }
                    Text(
                        text = "这是第二个子项",
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(50.dp)
                            .background(Color.Blue)
                    )
                }

            }
        }
    }

    /**
     * 学习指定可组合项的大小
     */
    @Composable
    private fun StudySize() {
        Column(
            modifier = Modifier
                .requiredSize(width = 50.dp, height = 300.dp)
                .background(color = Color.Red)
        ) {
        }
    }
复制代码

在上面的代码中,我们首先设置了一个Column,其中有三个可组合项,分别为TextBox和最后的一个Text,其中Box中的子可组合项的高度超过了Box所能提供的高度,运行的效果如下:

尺寸超过限制对父项的影响

从上面的运行结果可以看出:对于Column而言,相当于是后面的可组合项会覆盖前面的可组合项。

  1. 通过wrapContentSize(align,unbounded:Boolean)属性可以指定子项的对其方式。

设置这个属性,可组合项将会忽略所设置的最小宽度和最小高度,而是以其自身所需的实际大小进行绘制,如果内容的大小小于我们所设置的最小尺寸,那么就会按照我们指定的align参数对子项进行对齐。另外如果我们将unbounded参数设置为true,其还会忽略设置的最大宽度和最大高度,如下所示:

    @Composable
    private fun StudySize() {
        Column(
            modifier = Modifier
                .defaultMinSize(minWidth = 200.dp,minHeight = 200.dp)
                .wrapContentSize(align = Alignment.TopCenter)
                .background(color = Color.Red)
        ) {
            Text(
                text = "这是测试文本",
                modifier = Modifier
                    .size(50.dp, 100.dp)
                    .background(color = Color.Blue)
            )
        }
    }
复制代码

上面的代码中,我们设置了最外层Column的默认最小宽度和最小高度,如果我们不设置wrapContentSize属性,那么最终的效果就和我们上面单独使用defaultMinSize的效果是一样的,但是如果我们使用了wrapContentSize,则最终效果如下:

wrapContentSize的效果

通过上面的图片可以看出:虽然外层的Column尺寸比较大,但是背景并没有显示出来,而且其子项Text也是被放置在了父项的顶部居中的位置。从这里也可以看出,wrapContentSize并不会改变父项的大小,其最终的效果是让父项的相关属性以其自身所需的实际大小进行设置。

下面看一下当子项的大小超过父项大小的时候,我们将unbounded参数设置为true的效果:

    @Composable
    private fun StudySize() {
        Column(
            modifier = Modifier
                .size(200.dp)
                .wrapContentSize(align = Alignment.TopStart,unbounded = true)
                .background(color = Color.Red)

        ) {
            Text(
                text = "这是测试文本",
                modifier = Modifier
                    .size(300.dp)
                    .background(color = Color.Green),
                overflow = TextOverflow.Ellipsis

            )
        }
    }
复制代码

在上面的代码中,我们设置外层的Column的尺寸为200dp,但是其内部的子项Text的尺寸为300dp,如果我们设置unbounded为false,也就是默认值的话,那么Text超出父项的部分则不会显示出来,如果我们设置unbounded为true,那么父项设置的尺寸则会被忽略,而是使用子项实际需要的尺寸,也就是300dp。

下面是设置unbounded为false的情况:

unbounded为false

下面是设置unbounded为true的情况:

unbounded为true

另外,当我们的子项的尺寸大于父项的尺寸的时候,align属性则能指定子项相对于父项的对齐方式,下面演示了三个不同的对齐方式:

align设置为TopStart的时候:

align设置为TopStart

align设置为TopCenter的时候:

align设置为TopCenter

align设置为TopEnd的时候:

align设置为TopEnd

align设置为BottomEnd的情况:

align设置为BottomEnd

从上面图片可以看出,当子项的尺寸大于父项的尺寸,并且设置unbounded设置为true的时候,align属性其实是设置了绘制的起点,TopStart表示从左上角开始绘制,TopCenter则表示子项的中间和父项的中间对齐,TopEnd则表示子项的右上角和父项的右上角对齐。BottomEnd则表示子项的右下角和父项的右下角对齐。

  1. requiredSizeIn(minWidth,maxWidth,minHeight,maxHeight)方法可以将子项的大小限制在最大尺寸和最小尺寸之间,与此同时,如果自身所需的尺寸超过了父项所能提供的尺寸,则会忽略父项的限制,自顾自地使用自身的尺寸,就跟requiredSize()的效果一样,如下所示:
   override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Box(modifier = Modifier.fillMaxSize()) {
                Column(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.Center) {
                    Text(text = "这是第0个可组合项",modifier = Modifier.fillMaxWidth().height(50.dp).background(color = Color.Magenta))
                    Box(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(300.dp)
                            .background(color = Color(0xFF333333)),
                    ) {
                        StudySize()
                    }
                }

            }
        }
    }

    /**
     * 学习指定可组合项的大小
     */
    @Composable
    private fun StudySize() {
        Column(
            modifier = Modifier
                .requiredSizeIn(minWidth = 10.dp,maxWidth = 350.dp,minHeight = 10.dp,maxHeight = 350.dp)
                .background(color = Color.Red)

        ) {
            Text(
                text = "这是测试文本",
                modifier = Modifier
                    .size(400.dp)
                    .background(color = Color.Green),
                overflow = TextOverflow.Ellipsis

            )
        }
    }
复制代码

可以看到StudySize中的Column,它的父项所能提供的最大高度为300dp,但是它通过requiredSizeIn()设置的最大高度为350dp,而其子项所需的最大高度为400dp,下面是具体演示的效果:

requiredSizeIn演示

从上面的图片可以看出,当自身所需的最大高度大于父项所能提供的最大高度的时候,这里会忽略父项的限制,使用自身的尺寸。

总结

这篇学习笔记主要学习了通过size的相关方法设置可组合项的尺寸。还剩一个animateContentSize暂时不清楚如何使用,等后面再进行学习。

方法名 参数 说明
size Dp 使用传入的参数Dp设置可组合项的宽度和高度
size width:Dp,height:Dp 分别指定可组合项的宽度和高度
sizeIn minWidth:Dp,maxWidth:Dp,minHeight:Dp,maxHeight:Dp 指定可组合项的宽度和高度的范围
fillMaxSize fraction: Float 指定可组合项占满父项可用空间的比例,fraction取值为0 – 1之间,默认为1,表示占满父项提供的空间,如果设置为0.5则表示占满父项空间的一半,以此类推
defaultMinSize minWidth:Dp,minHeight:Dp 指定可组合项的最小宽度和最小高度
requiredSize Dp 强制设置可组合项的尺寸,忽略父项的尺寸限制,即使设置的可组合项的尺寸大于父项所提供的大小,仍然会按照设置的尺寸进行绘制
requiredSize width:Dp,height:Dp 强制设置可组合项的宽度和高度,忽略父项的尺寸限制
wrapContentSize align:Alignment,unbounded:Boolean 使父项忽略自身的大小限制,按照子项的实际尺寸进行绘制,注意这里并不会改变父项的大小,align参数用于指定子项大小和父项大小不同时的对齐方式,unbounded参数则用于当子项的尺寸超过了父项的限制的时候,是否仍然按照子项的尺寸进行绘制,true表示仍然忽略父项的限制,false表示保留父项的限制
requiredSizeIn minWidth:Dp,maxWidth:Dp,minHeight:Dp,maxHeight:Dp 一方面指定可组合项的尺寸范围,另一方面当自身尺寸超过父项的时候忽略父项的限制,使用自身大小进行绘制

尺寸相关的方法都比较容易理解,唯一比较难理解的就是wrapContentSize的使用,情况比较多。另外就是虽然可组合项尺寸较为容易指定,但是指定可组合项的属性的时候,顺序尤为重要,同样的属性,不同的顺序,可能最后的结果天差地别,这是和之前Android View机制很大的不同。下一篇学习笔记将会学习widthheight相关的方法,也是比较容易理解,和这篇笔记的方法几乎是一样的。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享