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

如何在指定Composable上方显示半透明加载遮罩(适配LazyRow)

解决方案:让LoadingBox遮罩仅覆盖目标Content且兼容LazyRow

问题根源

你的LoadingBox遮罩全屏是因为外层Box强制设置了fillMaxWidth(),且遮罩Surface用了fillMaxSize();而尝试固有测量时崩溃,是因为LazyRow基于SubcomposeLayout,不支持固有尺寸测量。

可行方案

通过matchParentSize修饰符让遮罩匹配content的实际尺寸,完全规避固有测量需求,同时保留组件灵活性:

@Composable
fun LoadingBox(
    modifier: Modifier = Modifier,
    isLoading: Boolean = false,
    loadingText: String,
    content: @Composable () -> Unit
) {
    Box(modifier = modifier) {
        content()
        if (isLoading) {
            Surface(
                modifier = Modifier
                    .matchParentSize()
                    .alpha(0.5f),
                color = MaterialTheme.colorScheme.surface
            ) {
                Column(
                    modifier = Modifier.fillMaxSize(),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    CircularProgressIndicator()
                    Text(text = loadingText)
                }
            }
        }
    }
}

关键改动说明

  1. 移除强制尺寸约束:去掉外层Box的fillMaxWidth()和wrapContentHeight(),让LoadingBox的尺寸由传入的modifier或content本身决定,避免遮罩强制占满屏幕。
  2. 使用matchParentSize:将遮罩Surface的fillMaxSize()替换为matchParentSize(),该修饰符会让Surface匹配父Box的尺寸(父Box尺寸由content测量结果决定),无需固有测量,完美兼容LazyRow。
  3. 添加遮罩背景色:给Surface设置color属性,确保半透明遮罩可见,可根据需求调整颜色和透明度。

使用示例

包裹LazyRow和文本框时,按钮不会被挤出,遮罩仅覆盖目标区域:

@Composable
fun Example() {
    Column(modifier = Modifier.padding(16.dp)) {
        LoadingBox(
            isLoading = true,
            loadingText = "加载中..."
        ) {
            Column {
                LazyRow(modifier = Modifier
                    .height(120.dp)
                    .background(Color.Gray)) {
                    items(10) {
                        Text("Item $it", modifier = Modifier.padding(8.dp))
                    }
                }
                TextField(value = "", onValueChange = {}, label = { Text("输入框") })
            }
        }
        Button(onClick = {}) {
            Text("操作按钮")
        }
    }
}

额外提示

  • 若需要LoadingBox占满父级宽度,可在使用时传入modifier = Modifier.fillMaxWidth(),保持组件灵活性。
  • matchParentSize仅能在Box的直接子元素中使用,当前结构完全符合要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:05:46