前言:本文使用UI框架Compose +Paging+Swiperefresh实现列表的下拉刷新,上拉加载更多功能
一、添加相关库包括viewModel ,Paging,Swiperefresh的Compose库
implementation ("androidx.emoji2:emoji2:1.3.0")//network & serializationimplementation ("com.google.code.gson:gson:2.9.0")implementation ("com.squareup.retrofit2:converter-gson:2.9.0")implementation ("com.squareup.retrofit2:retrofit:2.9.0")//implementation ("com.squareup.okhttp3:logging-interceptor:4.9.3")//swiperefresh 的compose 版本implementation ("com.google.accompanist:accompanist-swiperefresh:0.30.1")// paging 3 的compose 版本implementation ("androidx.paging:paging-compose:1.0.0-alpha18")//这个可以在Compose中得到viewmodelimplementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")//coil Compose 图片加载库implementation ("io.coil-kt:coil-compose:2.0.0-rc01")
二、MainActivity
class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {ComposeDemoTheme {// A surface container using the 'background' color from the themeSurface(modifier = Modifier.fillMaxSize(),color = MaterialTheme.colorScheme.background) {Greeting("Android")}}}}
}@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {ListContent()
}@Preview(showBackground = true)
@Composable
fun GreetingPreview() {ComposeDemoTheme {Greeting("Android")}
}@Composable
fun ListContent(){val viewModel:GithubViewModel= viewModel()val lazyPagingItems=viewModel.repositorPager.collectAsLazyPagingItems()val state:LazyListState= rememberLazyListState()SwipeRefresh(state =rememberSwipeRefreshState(lazyPagingItems.loadState.refresh is LoadState.Loading&&lazyPagingItems.itemCount > 0) ,onRefresh = { lazyPagingItems.refresh() }) {LazyColumn(state =state,contentPadding = PaddingValues(10.dp),verticalArrangement = Arrangement.SpaceEvenly){items(items=lazyPagingItems){item->item?.let {RepositorCard(it)}}if(lazyPagingItems.loadState.append is LoadState.Loading){item {Box(modifier = Modifier.fillMaxWidth().height(50.dp)){CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))}}}}if(lazyPagingItems.loadState.refresh is LoadState.Loading){if(lazyPagingItems.itemCount==0){Box(modifier = Modifier.fillMaxSize()) {CircularProgressIndicator(modifier = Modifier.align(alignment = Alignment.Center))}}}else if(lazyPagingItems.loadState.refresh is LoadState.Error){//加载失败的错误页面Box(modifier = Modifier.fillMaxSize()) {Button(modifier = Modifier.align(alignment = Alignment.Center),onClick = { lazyPagingItems.refresh() }) {Text(text = "加载失败!请重试")}}}}
}@Composable
fun RepositorCard(repositorItem: RepositorItem) {Card(modifier = Modifier.fillMaxWidth().padding(8.dp)) {Row(modifier = Modifier.fillMaxWidth().height(88.dp)) {Spacer(modifier = Modifier.width(10.dp))Surface(shape = CircleShape, modifier = Modifier.size(66.dp).align(Alignment.CenterVertically)) {AsyncImage(model = repositorItem.owner.avatar_url,contentDescription = "",contentScale = ContentScale.Crop)}Spacer(modifier = Modifier.width(15.dp))Column(modifier = Modifier.fillMaxWidth()) {Spacer(modifier = Modifier.height(8.dp))Text(text = repositorItem.name,)Text(text = repositorItem.full_name, style = MaterialTheme.typography.bodyMedium)}}}
}
三、MyPagingSource
class MyPagingSource(val githubService: GithubService = getGithubService(),val words: String,
) : PagingSource<Int, RepositorItem>() {override fun getRefreshKey(state: PagingState<Int, RepositorItem>): Int? {return state.anchorPosition?.let {val anchorPage = state.closestPageToPosition(it)anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)}}override suspend fun load(params: LoadParams<Int>): LoadResult<Int, RepositorItem> {try {val nextPage: Int = params.key ?: 1val repositorRst = githubService.searchRepositors(words, nextPage, 20)return LoadResult.Page(data = repositorRst.items,prevKey = if (nextPage == 1) null else nextPage - 1,nextKey = if (repositorRst.items.isEmpty()) null else nextPage + 1)}catch (e:Exception){return LoadResult.Error(e)}}
四、GithubViewModel
class GithubViewModel:ViewModel() {val repositorPager = Pager(config = PagingConfig(pageSize = 6)){MyPagingSource(getGithubService(),"compose")}.flow.cachedIn(viewModelScope)}
Demo下载:https://download.csdn.net/download/ange_li/90152118