Jetpack 中的 Itemdecoration compose

Itemdecoration in Jetpack compose

我目前正在评估我们是否可以在这个阶段将相当复杂的 UI 迁移到 Jetpack Compose,我正在努力解决以下问题。

我有一个无限滚动的垂直列表,其中包含各种不同的概念组件。其中一些是 headers,然后可以是一些文本,一些水平滚动(无限)列表,然后是一些分组组件,它们也垂直堆叠但概念上属于一个组。

@Compose
fun MyComplexList() {
 LazyColumn {
  item {
   // some header
  }
  item {
   // some horizontal content
   LazyRow {
    item {}
   }
  }
  item {
   // some other header
  }
  items(x) {
   // Some text for each item
  }
 }
}

正如人们所见,使用 compose 完成这件事相当简单,而且代码比编写这个复杂的 RecyclerView + Adapter 少得多...... 有一个例外:背景渐变,跨越(分组)Some infinite list of things 组件。 (图像中的倾斜渐变)

过去 (:D) 我会在 RecyclerView 上使用 ItemDecoration 跨多个项目绘制内容,但我找不到与 Compose 中类似的内容。

有人知道如何使用 compose 实现这一目标吗?

选项之一:

替换:

items(x) {
   // Some text for each item
}

与:

item {
   Column(modifier = Modifier.border(...).background(...)) { //Shape, color etc...
      x.forEach {
          // Some text for each item
      }
   }
}

经过你的回答,我明白了...

@Composable
fun ListWithBg() {
    val lazyListState = rememberLazyListState()
    val itemsCount = 50
    BoxWithConstraints(Modifier.fillMaxSize()) {
        ListBg(lazyListState, itemsCount, maxHeight) // see below
        LazyColumn(state = lazyListState, modifier = Modifier.fillMaxSize()) {
            item {
                Column(
                    Modifier
                        .fillMaxWidth()
                        .background(Color.White)
                ) {
                    Text(
                        text = "Some header",
                        style = MaterialTheme.typography.h5,
                        modifier = Modifier.padding(16.dp)
                    )
                }
            }

            item {
                Text(
                    text = "Some infinite list of things",
                    style = MaterialTheme.typography.h5,
                    modifier = Modifier.padding(16.dp)
                )
            }

            items(itemsCount) {
                Text(
                    text = "Item $it",
                    Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 16.dp, vertical = 6.dp)
                        .background(Color.LightGray)
                        .padding(8.dp)
                )
            }
        }
    }
}

要根据背景更改背景,您可以定义如下内容:

@Composable
fun ListBg(lazyListState: LazyListState, itemsCount: Int, maxHeight: Dp) {
    val firstVisibleIndex = lazyListState.firstVisibleItemIndex
    val totalVisibleItems = lazyListState.layoutInfo.visibleItemsInfo.size
    val hasNoScroll = itemsCount <= totalVisibleItems
    val totalHeight = if (hasNoScroll) maxHeight else maxHeight * 3
    val scrollableBgHeight = if (hasNoScroll) maxHeight else totalHeight - maxHeight
    val scrollStep = scrollableBgHeight / (itemsCount + 2 - totalVisibleItems)
    val yOffset = if (hasNoScroll) 0.dp else -(scrollStep * firstVisibleIndex)
    Box(
        Modifier
            .wrapContentHeight(unbounded = true, align = Alignment.Top)
            .background(Color.Yellow)
            .offset(y = yOffset)
    ) {
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .height(totalHeight)
                .drawBehind {
                    drawRoundRect(
                        Brush.linearGradient(
                            0f to Color.Red,
                            0.6f to Color.DarkGray,
                            1.0f to Color.Green,
                        ),
                    )
                }
        )
    }
}

结果如下: