Compose自定义布局的使用

本文介绍了在Android Compose中如何实现自定义布局,通过一个房源展示页面的需求,讲解了Compose自定义布局的实现步骤,包括测量子元素、计算布局尺寸、放置子元素以及添加竖直方向的居中和滚动能力。主要涉及的关键点有Modifier、Content和MeasurePolicy的使用。
摘要由CSDN通过智能技术生成

8ecae936e991f375fa6f8973d39ce60e.jpeg

 bf75d613220d95c043629fe6f600c752.gif 

本文字数:10501

预计阅读时间:27 分钟

Compose自定义布局的使用

我们知道,在Android View体系下,自定义布局需要继承ViewGroup重写onMeasure、onLayout方法,那么在Compose UI框架中该如何实现自定义布局呢?

今天我们就来学习下Compose UI中自定义布局的具体使用。

实现目标

项目中有一个房源展示页面,用来展示一栋楼的所有房间信息,布局要求如下:

  1. 每个房间的宽高尺寸固定,水平方向需要动态计算可以显示的房间数量,内容水平方向居中;

  2. 房源数量较少,无法充满屏幕时,房源在屏幕中竖直方向居中显示;

  3. 房源数量超过屏幕时,从上向下布局,竖直方向可以滑动查看。

我们以此页面为目标,学习Compose自定义布局的使用。

效果图

9ac0e739d6384828746d05687f982988.jpeg            

效果一:上下、左右居中

3eac8bafa497e7dfd4a0f5d6e918030a.gif            

效果二:上下滑动

Compose 自定义布局实现方式

在编写代码前,我们先来了解下Compose 中自定义布局的实现方式。

Compose中使用Layout 可组合项来实现自定义布局,在Layout函数中完成子元素的测量和放置。以下是 Layout 可组合项的函数签名:

@Composable inline fun Layout(
    content: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    measurePolicy: MeasurePolicy
) {}

一个自定义布局的Layout代码结构通常如下代码所示:

@Composable
fun MyBasicColumn(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        content = content
    ) { measurables, constraints ->
       
        // 1. 使用给定的约束条件constraints测量children
        val placeables = measurables.map { measurable ->
            measurable.measure(constraints)
        }

        // 2. 设置布局的尺寸,放置子元素
        layout(constraints.maxWidth, constraints.maxHeight) {
            var yPosition = 0
           //在父布局中放置children
            placeables.forEach { placeable ->
                placeable.placeRelative(x = 0, y = yPosition)
                yPosition += placeable.height
            }
        }
    }
}

从上面代码可以看到,Compose实现自定义布局,主要有两步:

  1. 测量每个子元素在父布局约束下的大小

  2. 确定布局尺寸,放置子元素

注意:Compose 界面不允许多遍测量。这意味着,布局元素不能为了尝试不同的测量配置而多次测量任何子元素。
主要参数介绍

Layout函数中,有三个主要参数:

1. modifer

由外部传入的修饰符,用来修饰我们自定义的这Layout 组件的一些属性或约束 Constraints;

2. content

自定义布局 Layout 组件中所包含的子元素 children;

3. measurePolicy

mearsurePolicy 参数是 MeasurePolicy 类型,它是一个函数式接口,指定了布局测量和放置项目的方式。我们通常在Layout函数中以尾随 Lambda 的形式提供 MeasurePolicy 作为参数,从而实现所需的 MeasureScope.measure 函数。

fun interface MeasurePolicy {
    fun MeasureScope.measure(
        measurables: List<Measurable>,
        constraints: Constraints
    ): MeasureResult
}

measure函数接受一个 Constraints 对象来告知 Layout 它的尺寸限制。Constraints 是一个简单类,用于限制 Layout 的最大和最小宽度与高度, constraints中提供的maxWidth和maxHeight是计算过modifier中padding之后的值, 所以布局中不需要再考虑padding:

class Constraints {
    val minWidth: Int
    val maxWidth: Int
    val minHeight: Int
    val maxHeight: Int
}

measure 函数还会接受 List&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值