设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间00 现在时间00 缓存数据 对自己狠一点,逼自己努力,再过几年你将会感谢今天发狠的自己、恨透今天懒惰自卑的自己。晚安!

对自己狠一点,逼自己努力,再过几年你将会感谢今天发狠的自己、恨透今天懒惰自卑的自己。晚安!

查看: 1261|回复: 0

Android Hilt Retrofit Paging3使用实例

[复制链接]

  离线 

TA的专栏

  • 打卡等级:即来则安
  • 打卡总天数:27
  • 打卡月天数:0
  • 打卡总奖励:360
  • 最近打卡:2025-09-26 06:00:19
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
377
主题
337
精华
0
金钱
1457
积分
770
注册时间
2023-2-10
最后登录
2025-9-26

发表于 2023-4-11 12:05:01 | 显示全部楼层 |阅读模式
效果视频

130629g4wwwmzeq1i4wabb.gif


简述

本Demo采用Hilt+Retrofit+Paging3完成,主要为了演示paging3分页功能的使用,下列为Demo所需要的相关依赖
  1. //retrofit
  2.     implementation 'com.squareup.retrofit2:retrofit:2.9.0'
  3.     implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
  4.     //paging
  5.     implementation 'androidx.paging:paging-runtime:3.1.1'
  6.     implementation 'androidx.paging:paging-compose:1.0.0-alpha14'
  7.     //Dagger - Hilt
  8.     implementation("com.google.dagger:hilt-android:2.44")
  9.     kapt("com.google.dagger:hilt-android-compiler:2.44")
  10.     // Compose dependencies
  11.     implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
  12.     implementation "androidx.hilt:hilt-navigation-compose:1.0.0"
  13.     // Coroutines
  14.     implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1'
  15.     implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
复制代码
Hilt+Retrofit


访问接口

定义需要访问的接口,此接口是Github api,
  1. suspend
复制代码
字段用于提示后续引用,此内容需要在协程中使用
  1. interface GithubService {
  2.     @GET("search/repositories?sort=stars&q=Android")
  3.     suspend fun queryGithubAsync(@Query("per_page")number:Int, @Query("page") page:Int):DetailsBean
  4. }
复制代码
网络实例

提供三个实例,最终外部需要引用的的为
  1. UseCase
复制代码
的实例,具体
  1. Hilt
复制代码
依赖注入此处不予说明,有意者可参考Hilt依赖注入
  1. @Module
  2. @InstallIn(SingletonComponent::class)
  3. object AppModule {
  4.     const val BASE_URL:String = "https://api.github.com/"
  5.     @Singleton
  6.     @Provides
  7.     fun providerRetrofit():Retrofit{
  8.         return Retrofit.Builder()
  9.             .baseUrl(BASE_URL)
  10.             .addConverterFactory(GsonConverterFactory.create())
  11.             .build()
  12.     }
  13.     @Singleton
  14.     @Provides
  15.     fun providerGithubService(retrofit: Retrofit): GithubService {
  16.         return retrofit.create(GithubService::class.java)
  17.     }
  18.     @Singleton
  19.     @Provides
  20.     fun providerUseCase(service: GithubService):UseCase{
  21.         return UseCase(GetProjects(service))
  22.     }
  23. }
复制代码
在Hilt提供的实例中,
  1. UseCase
复制代码
中实现了访问网络接口的任务
  1. data class UseCase(
  2.     val getProjects: GetProjects
  3. )
复制代码
  1. class GetProjects(private val service: GithubService) {
  2.     suspend operator fun invoke(number:Int,page:Int): DetailsBean {
  3.         return service.queryGithubAsync(number, page)
  4.     }
  5. }
复制代码
PagingSource

我们主要实现
  1. load
复制代码
方法;其中
  1. page
复制代码
为当前内容页数,
  1. pageSize
复制代码
为每页需要加载的内容数量(可在外部进行定义),
  1. repository
复制代码
为获取的网络数据实体,
  1. previousPage
复制代码
为前一页,此处做了一个判断,如果为第一页时,则返回null,否则进行滑动至上一页;
  1. nextPage
复制代码
为下一页,
  1. LoadResult.Page
复制代码
为分页加载所需的内容;
  1. LoadResult.Error
复制代码
可捕获异常
  1. class DataPagingSource(private val useCase: UseCase):PagingSource<Int,DetailBean>() {
  2.     override fun getRefreshKey(state: PagingState<Int, DetailBean>): Int? = null
  3.     override suspend fun load(params: LoadParams<Int>): LoadResult<Int, DetailBean> {
  4.        return try {
  5.            val page = params.key ?: 1 //当前页,默认第一页
  6.            val pageSize = params.loadSize //每页数据条数
  7.            val repository = useCase.getProjects(page,pageSize) //获取的数据源
  8.            val repositoryItem = repository.beans //获取的数据列表
  9.            val previousPage = if (page > 1) page - 1 else null //前一页
  10.            val nextPage = if (repositoryItem.isNotEmpty()) page+1 else null //下一页
  11.            Log.d("hiltViewModel","page=$page size=$pageSize")
  12.            LoadResult.Page(repositoryItem,previousPage,nextPage)
  13.        }catch (e:Exception){
  14.            LoadResult.Error(e)
  15.        }
  16.     }
  17. }
复制代码
ViewModel

在构造函数中调用Hilt构造的实例;其中
  1. getData
复制代码
方法为获取分页的数据,返回为
  1. Flow<PagingData<DetailBean>>
复制代码
类型,其中
  1. Flow<PagingData<...>>
复制代码
外部为固定写法,内部可根据需要自行定义,然后
  1. PagingConfig
复制代码
的配置中,我们需要配置
  1. pageSize
复制代码
  1. initialLoadSize
复制代码
,如果不定义后者,则通过每页内容数量会是
  1. pageSize
复制代码
的三倍,然后添加我们上述创建的
  1. PagingSource
复制代码
;最后转化为流,然后置于协程中,它缓存PagingData,以便此流的任何下游集合都将共享相同的数据
  1. @HiltViewModelclass HomeViewModel @Inject constructor(private val useCase: UseCase):ViewModel() {    val PAGE_SIZE = 10    fun getData():Flow<PagingData<DetailBean>>{        return Pager(            config = PagingConfig(pageSize = PAGE_SIZE, initialLoadSize = PAGE_SIZE),            pagingSourceFactory = { DataPagingSource(useCase) }        ).flow.cachedIn(viewModelScope)    }}
复制代码
View

获取ViewModel中的数据
  1. val datas = viewModel.getData().collectAsLazyPagingItems()
复制代码
同时如果需要添加底部刷新状态栏、数据错误等标识,需要监听
  1. loadState
复制代码
,其状态总共分为五种:

  • refresh:第一次加载数据触发
  • prepend:滑动上一页触发
  • append:滑动下一页触发
  • source:对应于[PagingSource]中的加载
  • mediator:对应于来自[RemoteMediator]的加载
我们此处主要使用
  1. refresh
复制代码
  1. append
复制代码

其中,在
  1. refresh
复制代码
中进行监听,如果然后数据为null,则显示全屏错误提示,此处为第一次加载数据;
然后,在
  1. append
复制代码
中监听
  1. loading
复制代码
  1. Error
复制代码
两种状态,在其
  1. loading
复制代码
是显示底部加载状态,在
  1. Error
复制代码
中显示底部错误提示,此处不同于
  1. refresh
复制代码
  1. Error
复制代码
状态,因为有了数据,就不在需要显示全屏错误提示,在数据列表底部显示错误状态栏即可
  1. @Composable
  2. fun GithubList(viewModel: HomeViewModel = hiltViewModel()){
  3.     val datas = viewModel.getData().collectAsLazyPagingItems()
  4.     LazyColumn(
  5.         verticalArrangement = Arrangement.spacedBy(10.dp),
  6.         modifier = Modifier
  7.             .background(grey)
  8.             .fillMaxSize()
  9.             .padding(10.dp)
  10.     ){
  11.         when(datas.loadState.refresh){
  12.             is LoadState.Loading-> {item {  loading() }}
  13.             is LoadState.Error-> {
  14.                 if (datas.itemCount <= 0){
  15.                     item{
  16.                         /**
  17.                          * 全屏显示错误*/
  18.                         failedScreen() {
  19.                             datas.retry()
  20.                         }
  21.                     }
  22.                 }
  23.             }
  24.         }
  25.         itemsIndexed(datas){ _, value ->
  26.             if (value != null){
  27.                 GithubItem(value)
  28.             }else{
  29.                 empty {
  30.                     datas.retry()
  31.                 }
  32.             }
  33.         }
  34.         when(datas.loadState.append){
  35.             is LoadState.NotLoading-> {}
  36.             is LoadState.Loading-> {
  37.                 item {
  38.                     loading()
  39.                 }
  40.             }
  41.             is LoadState.Error-> {
  42.                 if (datas.itemCount > 0){
  43.                     /**
  44.                      * 底部显示加载错误*/
  45.                     item { failed(){datas.retry()} }
  46.                 }
  47.             }
  48.         }
  49.     }
  50. }
复制代码
到此这篇关于Android Hilt Retrofit Paging3使用实例的文章就介绍到这了,更多相关Android Hilt Retrofit Paging3内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表