LazyColumn 进行无限次重组(Jetpack Compose)

LazyColumn doing infinite number of recompositions (Jetpack Compose)

我想使用 LazyColumn 显示项目列表。我编写了所需的代码,但是当我 运行 应用程序时,我发现 UI 非常滞后。我放了一些日志来找出问题可能出在哪里,我发现 LazyColumn 会无限地重组这些项目。我不知道为什么 LazyColumn 表现得像它那样

列出可组合项:

fun listOfReceivers(
    receivers: List<ReceivedPingItem>,
) {

    if (receivers.isNotEmpty()) {

        val listState = rememberLazyListState()
        val firstVisibleIndex = listState.firstVisibleItemIndex
        val lastVisibleItemIndex = listState.layoutInfo.visibleItemsInfo.lastIndex + listState.firstVisibleItemIndex

        if (listState.isScrolledToTheEnd()) {
            Log.d("*****", "Scrolled to the End")
            viewModel.onRecyclerViewScrolledToLast()
        }

        //LazyColumn -> equivalent of the RecyclerView
        LazyColumn(
            state = listState,
            contentPadding = PaddingValues(horizontal = 15.dp, vertical = 15.dp),
            verticalArrangement = Arrangement.spacedBy(8.dp),
        ) {
            items(receivers) { receiverItem ->
                Log.d("*****", "ADDED $receiverItem")

                ReceiversListItem(
                    receiver = receiverItem,
                    modifier = Modifier.fillMaxWidth()
                )
            }
        }
        // AppViewState
        if (firstVisibleIndex == 0) {
            appViewState.viewState = ViewState.ReceivedPingsViewState(firstVisibleIndex)
        } else {
            appViewState.viewState = ViewState.DefaultViewState
        }

        // Seen status check
        if (firstVisibleIndex != -1 && lastVisibleItemIndex != -1) {
            viewModel.onRecyclerViewScrolledSetViewed(
                receivers.subList(
                    firstVisibleIndex,
                    lastVisibleItemIndex
                )
            )
        }

    }
    else{
        EmptyPingsScreen()
    }
}

由于这个视频 - youtube.be/EOQB8PTLkpY?t=284,我做了这样的事情,并且效果很好:

@Composable
    fun ListOfReceivers(
        receivers: List<ReceivedPingItem>,
    ) {
        if (receivers.isNotEmpty()) {
            val listState = rememberLazyListState()

            val derivedListState by remember { derivedStateOf { listState.isScrolledToTheEnd() } }

            if (derivedListState) {
                viewModel.onRecyclerViewScrolledToLast()
            }

            // LazyColumn -> equivalent of the RecyclerView
            LazyColumn(
                state = listState,
                contentPadding = PaddingValues(horizontal = 15.dp, vertical = 15.dp),
                verticalArrangement = Arrangement.spacedBy(8.dp),
            ) {
                items(receivers) { receiverItem ->
                    Log.d("*****", "ADDED $receiverItem")
                    ReceiversListItem(
                        receiver = receiverItem,
                        modifier = Modifier.fillMaxWidth()
                    )
                }
            }

            // derivedStateOf - prevents infinite recomposition
            val visibleItemsCount by remember { derivedStateOf { listState.layoutInfo.visibleItemsInfo.size } }
            val firstVisibleItemIndex = listState.firstVisibleItemIndex
            val lastVisibleItemIndex = firstVisibleItemIndex + visibleItemsCount - 1

            // AppViewState
            if (firstVisibleItemIndex == 0) {
                appViewState.viewState = ViewState.ReceivedPingsViewState(firstVisibleItemIndex)
            } else {
                appViewState.viewState = ViewState.DefaultViewState
            }