前言:ComposeUI是将来开发的趋势,本人也在对它进行学习,会把踩过的坑一一记录下来,希望能对大家有帮助。话不多说,直接开干。
目录
下拉刷新
1、引入依赖库
2、使用方法
上拉加载
1、先看用法(结合下拉刷新):
2、具体实现
下拉刷新
下拉刷新有封装好的控件SwipeRefresh我们直接拿来用:
1、引入依赖库
repositories {mavenCentral()
}dependencies {implementation "com.google.accompanist:accompanist-swiperefresh:<version>"
}
注意:要根据自己项目中composeUI 的版本引入正确的版本号
2、使用方法
ViewModel:var isRefreshing by mutableStateOf(false)//用来控制SwipeRefresh的刷新状态private setUI:
SwipeRefresh(state = rememberSwipeRefreshState(isRefreshing = vm.isRefreshing),//用来控制SwipeRefresh的刷新状态onRefresh = {//刷新回调vm.loadTopArticle()vm.loadArticle(true)}) {LazyColum() {item {SwiperContent(dataSource = vm.swiperData)}items(vm.articleTopDataSource) { temp ->ArticleItem(item = temp, true)}}}
这个控件使用起来还是比较简单的,可以参考官网:Guide - Accompanist
上拉加载
上拉加载我没有找到成熟的三方库,不过通过看网上各种大神的帖子,自己整理了一套,使用逻辑和下拉刷新基本一致。具体如下
1、先看用法(结合下拉刷新):
viewModel:var loadMoreState by mutableStateOf(LoadMoreState.hasMore) //用来对loadmore状态控制private setUI:SwipeRefresh(state = rememberSwipeRefreshState(isRefreshing = vm.isRefreshing),//用来控制SwipeRefresh的刷新状态onRefresh = {//*刷新回调vm.loadTopArticle()vm.loadArticle(true)}) {LazyLoadMoreColum(loadMoreCallBack = {//*在加载更多的回调中去进行数据加载vm.loadArticle(false)}, loadMoreState = vm.loadMoreState //*用来控制上拉加载状态) {//以下内容跟LazyColum用法一样item {SwiperContent(dataSource = vm.swiperData)}items(vm.articleTopDataSource) { temp ->ArticleItem(item = temp, true)}items(vm.articleDataSource) { temp ->ArticleItem(item = temp, false)}}}
怎么样样式还算简洁吧。
2、具体实现
1、要实现加载更多肯定要判断LazyColum是否滚动到底部。LazyColum参数中有个LazyListState的实体,LazyListState的类中有一个layoutInfo参数,通过参数说明可以发现,通过它可以达到我们的目的。
/*** The object of [LazyListLayoutInfo] calculated during the last layout pass. For example,* you can use it to calculate what items are currently visible.*/val layoutInfo: LazyListLayoutInfo get() = layoutInfoState.value
对LazyListState进行扩展,代码如下(具体看注释):LazyListStateExt.kt
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.*/*** 扩展LazyColum的LazyListState,通过计算判断是否到达最后一项* @receiver LazyListState* @param buffer Int 指定离底部还剩几个时进行加载更多回调* @param loadMore Function0<Unit>*/
@Composable
fun LazyListState.OnBottomReached(buffer: Int = 0, loadMore: () -> Unit) {require(buffer >= 0) {"buffer 值必须是正整数"}//是否应该加载更多的状态val shouldLoadMore = remember {//因为状态由layoutInfo计算得到derivedStateOf {//列表为空的话直接返回trueval lastVisibleItem =layoutInfo.visibleItemsInfo.lastOrNull() ?: return@derivedStateOf true//如果现实项为最后一个item 返回truelastVisibleItem.index == layoutInfo.totalItemsCount - 1 - buffer}}LaunchedEffect(key1 = shouldLoadMore, block = {snapshotFlow {shouldLoadMore.value}.collect {if (it) {loadMore()}}})
}
2、对loadMore状态进行分析:
LoadMore有三种状态:可加载更多、已加载全部、加载更多出错。
enum class LoadMoreState {hasMore, //可加载更多内容noMore, //已加载完全部内容loadError //加载出错
}
3、封装LazyColum,对其根据加载状态追加加载状态提示。具体代码如下:LazyLoadMoreColum.kt
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.lifeidroid.wanandroid.ext.OnBottomReached/*** 为LazyColum增加加载更多提示* @param modifier Modifier* @param loadMoreState LoadMoreState* @param loadMore Function0<Unit>* @param content [@kotlin.ExtensionFunctionType] Function1<LazyListScope, Unit>*/
@Composable
fun LazyLoadMoreColum(modifier: Modifier = Modifier,loadMoreState: LoadMoreState = LoadMoreState.hasMore,loadMoreCallBack: () -> Unit,content: LazyListScope.() -> Unit
) {val lazyListState = rememberLazyListState()lazyListState.OnBottomReached {if (loadMoreState == LoadMoreState.hasMore) {loadMoreCallBack()}}LazyColumn(modifier, state = lazyListState) {content()//LoadMore的提示内容,可以根据自己的需求去自定义该部分显示样式item {Box(modifier = Modifier.clickable {if (loadMoreState == LoadMoreState.loadError) {loadMoreCallBack()}}.fillMaxWidth().padding(vertical = 8.dp),contentAlignment = Alignment.Center,) {Text(text = when (loadMoreState) {LoadMoreState.hasMore -> "正在加载.."LoadMoreState.noMore -> "没有更多数据了.."LoadMoreState.loadError -> "网络出错,点击重试!"},fontSize = 14.sp,color = Color.Gray)}}}
}
代码很简单,大家可以根据源码进行阅读理解,我就啰嗦了。希望对大家有帮助。