android Compose Paging 保留 LazyColumn 滚动位置

在使用过程中发现LazyColumn 的滚动位置丢失,经常是移动到0的位置,经过查询得解决方案为:
方案一:
重点为:

var listState=  if (logList.itemCount > 0) viewModel.listState else rememberLazyListState()

viewmodel

   var logPager = Pager(PagingConfig(pageSize = 10)) {
        LogPagingSource(Apifactory.apiService)
    }
  val logList = logPager.flow.cachedIn(viewModelScope)

页面使用

@Composable
fun testList(){
 val logList = viewModel.logList.collectAsLazyPagingItems()
var listState=  if (logList.itemCount > 0) viewModel.listState else rememberLazyListState()
...

 LazyColumn(
            modifier = Modifier
                .fillMaxHeight()
                .fillMaxWidth(),
            horizontalAlignment = Alignment.CenterHorizontally,
            state = listState
        ) 
...
}

方案二封装刷新
重点为:

if (collectAsLazyPagingItems.itemCount == 0 && refresh is LoadState.NotLoading) {
            return@SwipeRefresh
        }
//跳过虚拟状态,等待下一个撰写

具体实现为:

@Composable
fun  SwipeRefreshList(
    collectAsLazyPagingItems: LazyPagingItems,
    state: LazyListState = rememberLazyListState(),
    itemIndex: Int = 0,
    onRefresh: () -> Unit = {},
    content: LazyListScope.() -> Unit
) {
    val rememberSwipeRefreshState = rememberSwipeRefreshState(isRefreshing = false)
    SwipeRefresh(
        state = rememberSwipeRefreshState,
        onRefresh = {

            onRefresh.invoke()
        }) {
        val refresh = collectAsLazyPagingItems.loadState.refresh
        if (collectAsLazyPagingItems.itemCount == 0 && refresh is LoadState.NotLoading) {
            return@SwipeRefresh
        }

        //skip dummy state, waiting next compose

        rememberSwipeRefreshState.isRefreshing =
            collectAsLazyPagingItems.loadState.refresh is LoadState.Loading
        LazyColumn(
            modifier = Modifier
                .fillMaxHeight()
                .fillMaxWidth(),
            horizontalAlignment = Alignment.CenterHorizontally,
            state = state
        ) {

            content()

            collectAsLazyPagingItems.apply {
                when {
                    loadState.append is LoadState.Loading -> {//加载更多时,就在底部显示loading的item
                        item { LoadingItem() }
                    }
                    loadState.append is LoadState.Error -> {//加载更多的时候出错了,就在底部显示错误的item
                        item {
                            ErrorItem() {
                                collectAsLazyPagingItems.retry()
                            }
                        }
                    }
                    loadState.refresh is LoadState.Error -> {
                        if (collectAsLazyPagingItems.itemCount <= 0) {//刷新的时候,如果itemCount小于0,说明是第一次进来,出错了显示一个大的错误内容
                            /*item {
                                ErrorContent() {
                                    collectAsLazyPagingItems.retry()
                                }
                            }*/
                        } else {
                            item {
                                ErrorItem() {
                                    collectAsLazyPagingItems.retry()
                                }
                            }
                        }
                    }
                    loadState.append.endOfPaginationReached -> {
                        item {
                            FinishItem()
                        }
                    }
                }
            }
        }
        if (collectAsLazyPagingItems.loadState.refresh is LoadState.Error) {//加载更多的时候出错了,就在底部显示错误的item
            ErrorContent() {
                collectAsLazyPagingItems.retry()

            }

        }
    }
}


@Composable
fun ErrorItem(retry: () -> Unit) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(top = 5.dp, bottom = 12.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.Center,
    ) {
        OutlinedButton(
            onClick = retry,
            colors = ButtonDefaults.outlinedButtonColors(
                contentColor = grey_b4
            )
        ) {
            Text(text = "重新加载剩余数据", fontSize = 13.sp, color = grey_b4)
        }
    }

}

@Composable
fun ErrorContent(retry: () -> Unit) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .clickable { retry.invoke() },
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Image(
            modifier = Modifier.size(120.dp, 120.dp),
            painter = painterResource(id = R.drawable.ic_load_failed),
            contentDescription = "网络问题",
            contentScale = ContentScale.Fit
        )
        Spacer(modifier = Modifier.height(15.dp))
        Text(text = "网络不佳,请点击重试", fontSize = 13.sp, color = grey_b4)
    }
}


@Composable
fun LoadingContent() {
    val infiniteTransition = rememberInfiniteTransition()
    var angle = infiniteTransition.animateFloat(
        initialValue = 0F,
        targetValue = 360F,
        animationSpec = infiniteRepeatable(
            animation = tween(1500, easing = LinearEasing)
        )
    )
    Column(
        Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Image(
            painter = painterResource(id = R.drawable.ic_loading),
            contentDescription = "刷新",
            Modifier
                .size(90.dp)
                .padding(all = 5.dp)
                .graphicsLayer {
                    rotationZ = angle.value
                }
        )
        Spacer(modifier = Modifier.height(15.dp))
        Text(text = "数据加载中,请稍后", fontSize = 13.sp, color = black_3c)
    }
}

@Composable
fun LoadingItem() {
    Row(
        Modifier
            .fillMaxWidth()
            .padding(vertical = 4.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.Center
    ) {
        CircularProgressIndicator(
            strokeWidth = 2.dp,
            modifier = Modifier
                .size(24.dp),
            color = Purple500
        )
        Spacer(modifier = Modifier.width(10.dp))
        Text(text = "数据加载中", fontSize = 12.5.sp, color = black_3c)
    }
}

@Composable
fun FinishItem() {
    Text(
        modifier = Modifier
            .fillMaxWidth()
            .padding(13.dp),
        text = "加载完成",
        fontSize = 14.sp,
        color = black_3c,
        textAlign = TextAlign.Center
    )
}

来源:https://issuetracker.google.com/issues/177245496

你可能感兴趣的:(android Compose Paging 保留 LazyColumn 滚动位置)