Jetpack Compose 的Column , Row ,Box 的用法

8,959 阅读5分钟

前面文章我们讲了Jetpack Compose的环境的配置,还有一些Android Studio的针对Compose开发效率提升的一些工具介绍。现在开始讲Jetpack Compose的布局组件。先从Column,Row,Box讲起。

一:竖直布局 Column

学习Android的都知道,有个LinearLayout控件,该控件可以指定横向排列布局还是竖向排列。而Column的用法就相当于是竖向的排列的布局。

@Composable
fun columnTest(){
    Column {
        Text(text = "第一个文本控件,我是比较长的那个文本控件")
        Text(text = "第二个文本控件")
    }
}

比如上面的代码,我们竖直排列两个文本控件。使用起来很简单,我们来看看Column构造函数里面的几个代码。来简单介绍写构造函数里几个入参的用法。

@Composable
@OptIn(ExperimentalLayoutNodeApi::class, InternalLayoutApi::class)
inline fun Column(
    modifier: Modifier = Modifier,
    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
    content: @Composable ColumnScope.() -> Unit
) {
    ...
}
  • modifier修饰符。Modifier的介绍请看这篇文章
  • verticalArrangement Arrangement有几种取值方式,分别表示不同的意思。默认是Arrangement.Top表示竖直方式上尽可能的靠近主轴的顶部\
    • Arrangement.Top 垂直放置子对象,使其尽可能靠近主轴顶部。
    • Arrangement.BOTTOM 垂直放置子对象,使其尽可能靠近主轴底部。
    • Arrangement.CENTER 垂直子对象,使其尽可能靠近主轴的中间。
    • Arrangement.SpaceBetween 垂直放置子对象时,使它们沿主轴均匀分布,在第一个子对象之前或最后一个子对象之后没有可用空间。意思是第一个在最顶部,最后一个在最底部。而中间的按同等间隔去均分放置。
    • Arrangement.SpaceEvenly 垂直放置子对象,使他们同等间隔均分放置
    • Arrangement.SpaceAround 垂直放置子对象,第一个放置在距离顶部x间隔的地方,最后一个放置在距离底部x间隔的地方。中间的按同等间距均分放置。 几个属性如下图所示:发现康康写的的图更直观,所以图片直接借鉴康康的文章 block 举个例子,比如Column的高度是200dp,而两个文本控件的高度不足200dp,当设置底部对齐的时候,两个控件会在Column的底部
    @Preview()
    @Composable
    fun columnTest(){
        Column(
            // 设置Column的宽度高200dp
            modifier = Modifier.size(200.dp),
            // 设置居底部对齐
            verticalArrangement = Arrangement.Bottom){
            Text(text = "第一个文本控件ikkokokojih呼呼呼呼呼呼")
            Text(text = "第二个文本控件")
        }
    }
    
    默认是Arrangement.Top 当然我们也可以通过Arrangement.spacedBy()的方式去设置Column里item项的间距
    @Preview()
    @Composable
    fun columnTest(){
        Column(
            // 设置Column的宽度高200dp
            modifier = Modifier.size(200.dp),
            // 设置居底部对齐
            verticalArrangement = Arrangement.spacedBy(4.dp)){
            Text(text = "第一个文本控件ikkokokojih呼呼呼呼呼呼")
            Text(text = "第二个文本控件")
        }
    }
    
  • horizontalAlignment 表示是水平方向上的对齐方式。默认是从左边开始
    举个例子说明,比如上面两个文本控件,一个比较长,一个比较短。如果horizontalAlignment设置的是End。那么两个文本控件就会居右对齐。
    @Preview()
    @Composable
    fun columnTest(){
      Column(horizontalAlignment = Alignment.End){
          Text(text = "第一个文本控件,我是比较长的那个文本控件")
          Text(text = "第二个文本控件")
      }
    }
    
  • content 所有布局的最后一个参数都是 content,它是一个发出子界面元素的函数。其实上就是子元素的内容,比如这里就是两个Text文本控件。其实Column的完整的写法是如下:
    Column(
       content = {
        Text("Some text")
        Text("Some more text")
        Text("Last text")
      }
    )
    
    只不过是kotlin的lambda语法,Compose支持了。所以就把这种繁琐的写法简单的写成
      Column{
       Text("Some text")
       Text("Some more text")
       Text("Last text")
      }
    

二:横向布局 Row

使用 Row 可将多个项水平地放置在屏幕上。Row和Column一样都支持配置它们所含元素的对齐方式。我们还是拿两个文本控件来举例。两个文本控件横向排列

@Preview()
@Composable
fun rowTest(){
    Row{
        Text(text = "第一个文本控件ikkokokojih呼呼呼呼呼呼")
        Text(text = "   第二个文本控件")
    }
}

再来看看Row的源码

@Composable
@OptIn(ExperimentalLayoutNodeApi::class, InternalLayoutApi::class)
inline fun Row(
    modifier: Modifier = Modifier,
    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
    verticalAlignment: Alignment.Vertical = Alignment.Top,
    content: @Composable RowScope.() -> Unit
) {
   ...
}

我们可以看到跟Column一样。

  • modifier修饰符 Modifier的介绍请看这篇文章
  • horizontalArrangement 设置水平方向上的子view跟主轴的关系。默认是水平放置子view,居左开始布局Arrangement.Start。主要有如下几种取值
    • Arrangement.START 水平放置子对象,使其尽可能靠近主轴左边。
    • Arrangement.END 水平放置子对象,使其尽可能靠近主轴右边。
    • Arrangement.CENTER 水平放置子对象,使其尽可能靠近主轴的中间。
    • Arrangement.SpaceBetween 水平放置子对象时,使它们沿主轴均匀分布,在第一个子对象之前或最后一个子对象之后没有可用空间。意思是第一个在最左边,最后一个在最右部。而中间的按同等间隔去均分放置。
    • Arrangement.SpaceEvenly 水平放置子对象,使他们同等间隔均分放置
    • Arrangement.SpaceAround 水平放置子对象,第一个放置在距离顶部x间隔的地方,最后一个放置在距离底部x间隔的地方。中间的按同等间距均分放置。
  • verticalAlignment 设置竖直方向上对齐方式(由于Column讲解过这里就不举例了)
  • content 布局内容 (由于Column讲解过这里就不举例了)

三:Box (类似FramLayout布局)

使用 Box 可将一个元素放在另一个元素上,类似FramLayout布局。

  Box(Modifier.size(200.dp).background(Color.Red)){
      Text(text = "第一个文本控件ikkokokojih呼呼呼呼呼呼")
      Text(text = "第二个文本控件")
  }

比如上面这个例子就是第二个文本控件叠放在第一个文本控件上面。 再来看看Box的源码

@Composable
@OptIn(ExperimentalLayoutNodeApi::class)
inline fun Box(
    modifier: Modifier = Modifier,
    contentAlignment: Alignment = Alignment.TopStart,
    content: @Composable BoxScope.() -> Unit
) {
   ...
}
  • modifier修饰符 Modifier的介绍请看这篇文章
  • contentAlignment 是设置子控件的对齐方式,比如设置底部居中
    @Preview()
     @Composable
     fun boxTest(){
      Box(Modifier.size(300.dp).background(Color.Red),
      contentAlignment = Alignment.BottomCenter){
      Text(text = "第一个文本控件ikkokokojih呼呼呼呼呼呼")
      Text(text = "第二个文本控件")
      }
    }
    
  • content 布局内容 (由于Column讲解过这里就不举例了)

四:通过一张图片,清楚的知道Column,Row,Box

blockchain 通过我们通过各种空间的叠加组合,就可以构造出我们想要的界面。 注意:Compose 可以有效地处理嵌套布局,堪称设计复杂界面的绝佳工具。这与 Android Views 相比是一个进步;在 Android Views 中,出于性能方面的原因,您需要避免使用嵌套布局。