You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Compose自定义SegmentedControl:不等宽分段布局实现疑问

实现自适应宽度的SegmentedControl Composable组件问题

我正在实现一个SegmentedControl Composable组件,希望支持分段根据内容需求展示不同宽度。目前已实现所有分段宽度相等的基础版本:

当前效果:三个分段(Foo、Bar、Some very long string)宽度完全均分,其中Foo和Bar实际不需要这么宽,浪费了空间,应该给长文本分段留出更多位置。

核心需求

  • 当所有子项所需宽度总和小于布局约束宽度时,均分空间
  • 否则收缩可压缩的子项,直至所有子项可见
  • 若无法全部显示,找到能展示最多内容的布局方式

实现第一个需求时遇到的问题

尝试实现第一个需求时,发现默认Layout Composable不允许对Measurable进行多次测量,以下代码无法运行:

Layout(
    content = {
        // Segments
    }
) { segmentsMeasurables, constraints ->
    var placeables = segmentsMeasurables.map {
        it.measure(constraints)
    }
    // 当所有子项总宽度小于布局最大宽度时,均分空间
    if (placeables.sumOf { it.measuredWidth } <= constraints.maxWidth) {
        placeables = segmentsMeasurables.map { 
            it.measure( // <- 不允许重复测量!
                Constraints.fixed(
                    width = constraints.maxWidth / state.segmentCount,
                    height = placeables[0].height
                )
            )
        }
    }

    layout(
        width = placeables.sumOf { it.width },
        height = placeables[0].height
    ) {
        var xOffset = 0
        placeables.forEachIndexed { index, placeable ->
            xOffset += placeables.getOrNull(index - 1)?.width ?: 0
            placeable.placeRelative(
                x = xOffset,
                y = 0
            )
        }
    }
}

其他尝试与疑问

我也了解过SubcomposeLayout,但它似乎不符合我的需求(我的场景不需要子组合)。

我能想到一种不太规范的方案:强制至少两次布局遍历收集子项尺寸,再执行布局逻辑,但这会不稳定、性能差,还会出现布局错乱的帧。

请问正确的实现方式是什么?我是否遗漏了什么?


内容的提问来源于stack exchange,提问作者Calamity

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 20:40:25