[Jetpack compose]FlowLayout的简单实现

749 阅读1分钟

前言

  本文已参与「新人创作礼」活动,一起开启掘金创作之路。  

最近在学习compose,想用做一个pc端的Adb的工具箱来方便开发,刚好compose desktop又可以开发pc应用,于是便有了这个界面:

QQ图片20220117221841.png

但是,pc应用的窗口大小是可以调整的,如果窗口的宽度变小,如果使用Row()的话,横向排列的按钮会挤在一起:

QQ图片20220117222726.png

话不多说,马上开始

@Composable
fun FlowLayout(modifier: Modifier = Modifier, horizontalSpace: Int = 0,verticalSpace:Int=0, content: @Composable () -> Unit) {
    Layout(modifier = modifier, content = content) { measurables, constraints -> 
    //measurables是需要测量的子项列表  constraints是来自父布局的测量约束
    //下文中的measurable和placeables都可以理解为父布局的子项(它们只是子项的不同形态)
        val placeables = measurables.map { measurable->
        //1、可测量子项根据父布局约束进行测量,得到可放置项
           val placeable =  measurable.measure(constraints)
            placeable
        }
        //2、记录子项每次放置的位置
        var xPosition = 0
        var yPosition = 0
        
        layout(constraints.maxWidth,constraints.maxHeight){
        //3、使用layout函数对每一个子项进行布局
            placeables.forEach {
                if(xPosition + it.width + horizontalSpace> constraints.maxWidth){
                    //一行已经放不下,需要换行
                    yPosition+=it.height+verticalSpace
                    xPosition = 0
                }
                it.placeRelative(x = xPosition,y = yPosition)
                //4、每次放置子项后,更新下一个子项放置的位置
                xPosition += it.width+horizontalSpace
            }
        }
    }
}
//代码中的horizontalSpace和verticalSapce指子项之间的间隔。

四个步骤

1、可测量子项根据父布局约束进行测量,得到可放置项
2、记录子项每次放置的位置
3、使用layout函数对每一个子项进行布局
4、每次放置子项后,更新下一个子项放置的位置

附上调用代码

FlowLayout(modifier = Modifier, horizontalSpace = 10) {
    Button(onClick = { viewModel.reboot() }) {
        Text("重启设备")
    }
    Button(onClick = { viewModel.getAndroidVersion() }) {
        Text("Android版本号")
    }
    Button(onClick = { viewModel.getCurrentActivity() }) {
        Text("当前Activity")
    }

    Button(onClick = { viewModel.getDevices() }) {
        Text("已连接设备")
    }
    Button(onClick = { viewModel.getConnectionState() }) {
        Text("设备状态")
    }
}

最终效果

Video_20220117_104930_625.gif