【问题标题】:Does Jetpack Compose's LazyVerticalGrid have span strategyJetpack Compose 的 LazyVerticalGrid 是否有 span 策略
【发布时间】:2021-01-31 15:52:43
【问题描述】:

我有一个带有 2 个单元格的 LazyVerticalGrid。

LazyVerticalGrid(
    cells = GridCells.Fixed(2),
    content = {
        items(moviePagingItems.itemCount) { index ->
            val movie = moviePagingItems[index] ?: return@items
            MovieItem(movie, Modifier.preferredHeight(320.dp))
        }
        renderLoading(moviePagingItems.loadState)
    }
)

我正在尝试使用LazyGridScopefillParentMaxSize 修饰符显示全宽度加载。

fun LazyGridScope.renderLoading(loadState: CombinedLoadStates) {
  when {
    loadState.refresh is LoadState.Loading -> {
        item {
            LoadingColumn("Fetching movies", Modifier.fillParentMaxSize())
        }
    }
    loadState.append is LoadState.Loading -> {
        item {
            LoadingRow(title = "Fetching more movies")
        }
    }
  }
}

但是由于我们有 2 个单元格,加载可以占据屏幕的一半。像这样:

有没有办法让我的加载视图占据整个宽度?

【问题讨论】:

    标签: android android-jetpack-compose


    【解决方案1】:

    尝试类似:

    var cellState by remember { mutableStateOf(2) }
    LazyVerticalGrid(
        cells = GridCells.Fixed(cellState),
        content = {
            items(moviePagingItems.itemCount) { index ->
                val movie = moviePagingItems[index] ?: return@items
                MovieItem(movie, Modifier.preferredHeight(320.dp))
            }
            renderLoading(moviePagingItems.loadState) {
                cellState = it
            }
        }
    )
    

    renderLoading 函数:

    fun LazyGridScope.renderLoading(loadState: CombinedLoadStates, span: (Int) -> Unit) {
        when {
            loadState.refresh is LoadState.Loading -> {
                item {
                    LoadingColumn("Fetching movies", Modifier.fillParentMaxSize())
                }
                span(1)
            }
            ...
            else -> span(2)
        }
      
    }
    

    【讨论】:

    • 这是一个绝妙的主意,谢谢。但我还有另一个问题。我有分页,当loadState.append 时我无法更改网格单元数,因为我已经有项目了。
    【解决方案2】:

    我为它创建了一个问题:https://issuetracker.google.com/u/1/issues/176758183

    我目前的解决方法是使用LazyColumn 并实现项目或标题。

    override val content: @Composable () -> Unit = {
        LazyColumn(
                contentPadding = PaddingValues(8.dp),
                content = {
                    items(colors.chunked(3), itemContent = {
    
                        Row(horizontalArrangement = Arrangement.SpaceEvenly) {
                            val modifier = Modifier.weight(1f)
                            it.forEach {
                                ColorItem(modifier, it)
                            }
                            for (i in 1..(3 - it.size)) {
                                Spacer(modifier)
                            }
                        }
                    })
                    item {
                        Text(
                                text = stringResource(R.string.themed_colors),
                                style = MaterialTheme.typography.h3
                        )
                    }
                    items(themedColors.chunked(3), itemContent = {
                        Row(horizontalArrangement = Arrangement.SpaceEvenly) {
                            val modifier = Modifier.weight(1f)
                            it.forEach {
                                ColorItem(modifier, it)
                            }
                            for (i in 1..(3 - it.size)) {
                                Spacer(modifier)
                            }
                        }
                    })
                })
    }
    

    【讨论】:

    • 我有这种行为,分页列表给了我意想不到的展示位置。否则,这暂时有效。
    • 那么问题可能与网格无关。您是否尝试过每行一个项目只是为了看看它是否适用于分页?
    • 嗯,如果没有看到更多代码,我不能说更多。
    【解决方案3】:

    Jetpack Compose 1.1.0-beta03 版本包括对 LazyVerticalGrid 的水平跨度支持。

    以下是示例用法:

    private const val CELL_COUNT = 2
    
    private val span: (LazyGridItemSpanScope) -> GridItemSpan = { GridItemSpan(CELL_COUNT) }
    
    LazyVerticalGrid(
        cells = GridCells.Fixed(CELL_COUNT),
        content = {
            items(moviePagingItems.itemCount) { index ->
                val movie = moviePagingItems.peek(index) ?: return@items
                Movie(movie)
            }
            renderLoading(moviePagingItems.loadState)
        }
    }
    
    private fun LazyGridScope.renderLoading(loadState: CombinedLoadStates) {
        if (loadState.append !is LoadState.Loading) return
    
        item(span = span) {
            val title = stringResource(R.string.fetching_more_movies)
            LoadingRow(title = title)
        }
    }
    

    可以在以下位置找到此答案的代码示例:Jetflix/MoviesGrid.kt

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-06
      • 1970-01-01
      • 2022-10-07
      • 1970-01-01
      相关资源
      最近更新 更多