V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
magic3584
V2EX  ›  Android

请教个 Jetpack Compose 的布局问题

  •  
  •   magic3584 · 8 小时 31 分钟前 · 592 次点击

    我想做一个类似物流的一个页面类似下图,但是左边那条绿线无法显示出来。(代码和图片在后面)

    1. Row(modifier = Modifier.height(IntrinsicSize.Min)) 并且把图片 grid 注释掉,那么绿线是正常显示的
    2. Row(modifier = Modifier.fillMaxHeight)并且设置 grid 的 height ,也无法显示 img
    @Composable
    fun ListDemo() {
        var titles = listOf("1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2","1","2")
        LazyColumn(modifier = Modifier
            .fillMaxSize()) {
            itemsIndexed(titles) { index, item ->
                Surface(modifier = Modifier
                    .fillMaxWidth()) {
                    Column(modifier = Modifier
                        .padding(horizontal = 18.dp)) {
                        Row(modifier = Modifier
                            .padding(vertical = 8.dp),
                            verticalAlignment = Alignment.CenterVertically) {
                            Box(modifier = Modifier
                                .size(24.dp)
                                .background(Color.Red))
                        }
    
                        Row(modifier = Modifier
                            .fillMaxWidth()) {
                            Box(modifier = Modifier
                                .width(24.dp)
                                .fillMaxHeight(IntrinsicSize.Min),
                                contentAlignment = Alignment.Center){
                                // TODO show this green line
                                Box(modifier = Modifier
                                    .fillMaxHeight()
                                    .width(1.dp)
                                    .background(Color.Green))
                            }
                            Spacer(Modifier.width(8.dp))
                            Column(modifier = Modifier
                                .fillMaxWidth(),
                                verticalArrangement = Arrangement.spacedBy(8.dp)) {
                                Row(modifier = Modifier
                                    .fillMaxWidth()) {
                                    Text(
                                        text = "Time:",
                                        fontSize = 14.sp,
                                        color = Color.Gray,
                                        modifier = Modifier
                                            .width(100.dp)
                                    )
                                    Spacer(Modifier.width(4.dp))
                                    Text(
                                        text = "2023-03-02 18:34:07",
                                        fontSize = 14.sp,
                                        color = Color.Gray
                                    )
                                }
    
                                val images = listOf("1","2","3","4")
                                LazyVerticalGrid(
                                    columns = GridCells.Fixed(3),
                                    horizontalArrangement = Arrangement.spacedBy(6.dp),
                                    verticalArrangement = Arrangement.spacedBy(6.dp),
                                    modifier = Modifier.heightIn(
                                        max = 1000.dp)
                                ) {
                                    items(images) { pic ->
                                        Box(
                                            modifier = Modifier
                                                .aspectRatio(1f)
                                                .background(Color.Gray)
                                        ) {
                                            Text(
                                                text = pic
                                            )
                                        }
                                    }
                                }
    
                            }
                        }
    
                        Spacer(Modifier.height(8.dp))
                    }
    
    
                }
            }
        }
    }
    
    @Preview
    @Composable
    fun ListDemoPreview() {
        ListDemo()
    }
    
    12 条回复    2025-03-13 20:08:04 +08:00
    vigroid
        1
    vigroid  
       8 小时 4 分钟前
    Column( weight = 1f ) , 不要加上 fillMaxWidth()。占据剩余的空间应该用 weight = 1f
    magic3584
        2
    magic3584  
    OP
       7 小时 54 分钟前
    @vigroid
    不行,右侧 Column 用 weight(1) 或者 fillMaxWidth() 这里是同样的效果
    qwell
        3
    qwell  
       7 小时 23 分钟前
    Row(modifier = Modifier.height(IntrinsicSize.Min)) {
    Box(modifier = Modifier
    .width(24.dp)
    .fillMaxHeight(),
    contentAlignment = Alignment.Center){
    Box(modifier = Modifier
    .fillMaxHeight()
    .width(1.dp)
    .background(Color.Green))
    }
    Spacer(Modifier.width(8.dp))
    Column(modifier = Modifier
    .weight(1f),
    verticalArrangement = Arrangement.spacedBy(8.dp)) {...}
    }
    这样,有一点是两个 LazyLayout 滑动冲突了
    magic3584
        4
    magic3584  
    OP
       7 小时 10 分钟前
    @qwell #3
    不行,还是会报错
    ```shell
    java. lang. IllegalStateException: Asking for intrinsic measurements of SubcomposeLayout layouts is not supported. This includes components that are built on top of SubcomposeLayout, such as lazy lists, BoxWithConstraints, TabRow, etc. To mitigate this: - if intrinsic measurements are used to achieve 'match parent' sizing, consider replacing the parent of the component with a custom layout which controls the order in which children are measured, making intrinsic measurement not needed - adding a size modifier to the component, in order to fast return the queried intrinsic measurement.
    ```
    jojo0830
        5
    jojo0830  
       7 小时 7 分钟前
    动态获取 Column 的高度吧。
    Column(
    modifier = Modifier
    .fillMaxWidth()
    .onSizeChanged {
    sizeInDp = with(density) {
    it.width.toDp() to it.height.toDp()
    }
    },
    verticalArrangement = Arrangement.spacedBy(8.dp)
    ),
    然后把高度给到 box 。
    Box(
    modifier = Modifier
    .width(24.dp)
    .height(sizeInDp.second)
    .background(Color.Red),
    contentAlignment = Alignment.Center
    )
    jojo0830
        6
    jojo0830  
       7 小时 7 分钟前
    @jojo0830 但是你这样绿色也没跟红色方块接触,不好看,重新调整布局吧
    qwell
        7
    qwell  
       7 小时 5 分钟前 via Android
    @magic3584 因为你嵌套了两个 lazylayout ,你把里面的 lazyverticalgrid 设个固定高度
    od66666666
        8
    od66666666  
       6 小时 18 分钟前
    遇 size 不决,直接 onGloballyPositioned

    Row(modifier = Modifier.fillMaxWidth()) {
    val density = LocalDensity.current
    var columnHeight by remember { mutableStateOf(0.dp) }
    Box(
    modifier = Modifier
    .height(columnHeight)
    .width(24.dp),
    contentAlignment = Alignment.Center
    ) {
    ...
    }
    Spacer(Modifier.width(8.dp))
    Column(modifier = Modifier
    .onGloballyPositioned { layoutCoordinates ->
    columnHeight =
    with(density) { layoutCoordinates.size.height.toDp() }
    }
    .fillMaxWidth(),
    verticalArrangement = Arrangement.spacedBy(8.dp)) {
    ...
    }
    }
    lisongeee
        9
    lisongeee  
       5 小时 53 分钟前
    上面报错已经说得很明白了,你的子布局有无法确定 size 的组件 LazyVerticalGrid

    LazyXXX 就是前端概念里的虚拟列表,必须要一个容器高度才能计算虚拟滚动

    或者换成自定义 Column{Row{}}
    zeropercenthappy
        10
    zeropercenthappy  
       5 小时 43 分钟前
    从你的布局来看,内部的列表应该没有必要使用 LazyVerticalGrid ,这里应该是 Lazy 控件导致的高度计算问题。考虑直接换成 FlowRow 吧。
    leiiiooo
        11
    leiiiooo  
       5 小时 23 分钟前
    使用 Canvas 自定义吧,我也试了半天😂
    lisongeee
        12
    lisongeee  
       5 小时 7 分钟前   ❤️ 1
    https://gist.github.com/lisonge/b689ea150c7df8ae2618c4f73203ad9e

    整了半天,发现在外面套个 box 就行,代码和运行截图都在上面的 gist 里了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1401 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 17:15 · PVG 01:15 · LAX 10:15 · JFK 13:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.