在使用过程中发现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 <T : Any> SwipeRefreshList(
collectAsLazyPagingItems: LazyPagingItems<T>,
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
)
}