Android?Hilt?Retrofit?Paging3使用實(shí)例
效果視頻

簡(jiǎn)述
本Demo采用Hilt+Retrofit+Paging3完成,主要為了演示paging3分頁(yè)功能的使用,下列為Demo所需要的相關(guān)依賴
//retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
//paging
implementation 'androidx.paging:paging-runtime:3.1.1'
implementation 'androidx.paging:paging-compose:1.0.0-alpha14'
//Dagger - Hilt
implementation("com.google.dagger:hilt-android:2.44")
kapt("com.google.dagger:hilt-android-compiler:2.44")
// Compose dependencies
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
implementation "androidx.hilt:hilt-navigation-compose:1.0.0"
// Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
Hilt+Retrofit
訪問接口
定義需要訪問的接口,此接口是Github api,suspend字段用于提示后續(xù)引用,此內(nèi)容需要在協(xié)程中使用
interface GithubService {
@GET("search/repositories?sort=stars&q=Android")
suspend fun queryGithubAsync(@Query("per_page")number:Int, @Query("page") page:Int):DetailsBean
}
網(wǎng)絡(luò)實(shí)例
提供三個(gè)實(shí)例,最終外部需要引用的的為UseCase的實(shí)例,具體Hilt依賴注入此處不予說明,有意者可參考Hilt依賴注入
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
const val BASE_URL:String = "https://api.github.com/"
@Singleton
@Provides
fun providerRetrofit():Retrofit{
return Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
@Singleton
@Provides
fun providerGithubService(retrofit: Retrofit): GithubService {
return retrofit.create(GithubService::class.java)
}
@Singleton
@Provides
fun providerUseCase(service: GithubService):UseCase{
return UseCase(GetProjects(service))
}
}
在Hilt提供的實(shí)例中,UseCase中實(shí)現(xiàn)了訪問網(wǎng)絡(luò)接口的任務(wù)
data class UseCase(
val getProjects: GetProjects
)
class GetProjects(private val service: GithubService) {
suspend operator fun invoke(number:Int,page:Int): DetailsBean {
return service.queryGithubAsync(number, page)
}
}
PagingSource
我們主要實(shí)現(xiàn)load方法;其中page為當(dāng)前內(nèi)容頁(yè)數(shù),pageSize為每頁(yè)需要加載的內(nèi)容數(shù)量(可在外部進(jìn)行定義),repository為獲取的網(wǎng)絡(luò)數(shù)據(jù)實(shí)體,previousPage為前一頁(yè),此處做了一個(gè)判斷,如果為第一頁(yè)時(shí),則返回null,否則進(jìn)行滑動(dòng)至上一頁(yè);nextPage為下一頁(yè), LoadResult.Page為分頁(yè)加載所需的內(nèi)容; LoadResult.Error可捕獲異常
class DataPagingSource(private val useCase: UseCase):PagingSource<Int,DetailBean>() {
override fun getRefreshKey(state: PagingState<Int, DetailBean>): Int? = null
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, DetailBean> {
return try {
val page = params.key ?: 1 //當(dāng)前頁(yè),默認(rèn)第一頁(yè)
val pageSize = params.loadSize //每頁(yè)數(shù)據(jù)條數(shù)
val repository = useCase.getProjects(page,pageSize) //獲取的數(shù)據(jù)源
val repositoryItem = repository.beans //獲取的數(shù)據(jù)列表
val previousPage = if (page > 1) page - 1 else null //前一頁(yè)
val nextPage = if (repositoryItem.isNotEmpty()) page+1 else null //下一頁(yè)
Log.d("hiltViewModel","page=$page size=$pageSize")
LoadResult.Page(repositoryItem,previousPage,nextPage)
}catch (e:Exception){
LoadResult.Error(e)
}
}
}
ViewModel
在構(gòu)造函數(shù)中調(diào)用Hilt構(gòu)造的實(shí)例;其中getData方法為獲取分頁(yè)的數(shù)據(jù),返回為Flow<PagingData<DetailBean>>類型,其中Flow<PagingData<...>>外部為固定寫法,內(nèi)部可根據(jù)需要自行定義,然后PagingConfig的配置中,我們需要配置pageSize和initialLoadSize,如果不定義后者,則通過每頁(yè)內(nèi)容數(shù)量會(huì)是pageSize的三倍,然后添加我們上述創(chuàng)建的PagingSource;最后轉(zhuǎn)化為流,然后置于協(xié)程中,它緩存PagingData,以便此流的任何下游集合都將共享相同的數(shù)據(jù)
@HiltViewModel
class 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中的數(shù)據(jù)
val datas = viewModel.getData().collectAsLazyPagingItems()
同時(shí)如果需要添加底部刷新狀態(tài)欄、數(shù)據(jù)錯(cuò)誤等標(biāo)識(shí),需要監(jiān)聽loadState,其狀態(tài)總共分為五種:
- refresh:第一次加載數(shù)據(jù)觸發(fā)
- prepend:滑動(dòng)上一頁(yè)觸發(fā)
- append:滑動(dòng)下一頁(yè)觸發(fā)
- source:對(duì)應(yīng)于[PagingSource]中的加載
- mediator:對(duì)應(yīng)于來自[RemoteMediator]的加載
我們此處主要使用refresh和append;
其中,在refresh中進(jìn)行監(jiān)聽,如果然后數(shù)據(jù)為null,則顯示全屏錯(cuò)誤提示,此處為第一次加載數(shù)據(jù);
然后,在append中監(jiān)聽loading和Error兩種狀態(tài),在其loading是顯示底部加載狀態(tài),在Error中顯示底部錯(cuò)誤提示,此處不同于refresh的Error狀態(tài),因?yàn)橛辛藬?shù)據(jù),就不在需要顯示全屏錯(cuò)誤提示,在數(shù)據(jù)列表底部顯示錯(cuò)誤狀態(tài)欄即可
@Composable
fun GithubList(viewModel: HomeViewModel = hiltViewModel()){
val datas = viewModel.getData().collectAsLazyPagingItems()
LazyColumn(
verticalArrangement = Arrangement.spacedBy(10.dp),
modifier = Modifier
.background(grey)
.fillMaxSize()
.padding(10.dp)
){
when(datas.loadState.refresh){
is LoadState.Loading-> {item { loading() }}
is LoadState.Error-> {
if (datas.itemCount <= 0){
item{
/**
* 全屏顯示錯(cuò)誤*/
failedScreen() {
datas.retry()
}
}
}
}
}
itemsIndexed(datas){ _, value ->
if (value != null){
GithubItem(value)
}else{
empty {
datas.retry()
}
}
}
when(datas.loadState.append){
is LoadState.NotLoading-> {}
is LoadState.Loading-> {
item {
loading()
}
}
is LoadState.Error-> {
if (datas.itemCount > 0){
/**
* 底部顯示加載錯(cuò)誤*/
item { failed(){datas.retry()} }
}
}
}
}
}
到此這篇關(guān)于Android Hilt Retrofit Paging3使用實(shí)例的文章就介紹到這了,更多相關(guān)Android Hilt Retrofit Paging3內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android編程實(shí)現(xiàn)在Bitmap上涂鴉效果
這篇文章主要介紹了Android編程實(shí)現(xiàn)在Bitmap上涂鴉效果的方法,涉及Android界面布局,事件響應(yīng)及Bitmap操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-12-12
Android 中ContentProvider的實(shí)例詳解
這篇文章主要介紹了Android 中ContentProvider的實(shí)例詳解的相關(guān)資料,希望通過本文大家能掌握這部分內(nèi)容,需要的朋友可以參考下2017-09-09
Android開發(fā)中畫廊視圖Gallery的兩種使用方法分析
這篇文章主要介紹了Android開發(fā)中畫廊視圖Gallery的兩種使用方法,結(jié)合實(shí)例形式分析了Android畫廊視圖Gallery的簡(jiǎn)單布局與功能實(shí)現(xiàn)相關(guān)操作技巧,需要的朋友可以參考下2018-01-01
Android自定義View控件實(shí)現(xiàn)刷新效果
這篇文章主要介紹了Android自定義View控件實(shí)現(xiàn)刷新效果的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11
Android學(xué)習(xí)筆記之應(yīng)用單元測(cè)試實(shí)例分析
這篇文章主要介紹了Android學(xué)習(xí)筆記之應(yīng)用單元測(cè)試,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android單元測(cè)試的實(shí)現(xiàn)原理與具體步驟,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
Android?NDK入門初識(shí)(組件結(jié)構(gòu)開發(fā)流程)
這篇文章主要為大家介紹了Android?NDK入門之初識(shí)組件結(jié)構(gòu)開發(fā)流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
Flutter桌面開發(fā)windows插件開發(fā)
這篇文章主要為大家介紹了Flutter桌面開發(fā)windows插件開發(fā)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
使用Docker來加速構(gòu)建Android應(yīng)用的基本部署思路解析
這篇文章主要介紹了使用Docker來加速構(gòu)建Android應(yīng)用的部署思路解析,在服務(wù)器中通過Docker鏡像來獲得更高效的開發(fā)和測(cè)試流程,需要的朋友可以參考下2016-01-01
Android viewpager 3D畫廊的實(shí)現(xiàn)方法
ViewPager在開發(fā)中的使用頻率非常的高,接下來通過本文給大家分享android viewpager 3D畫廊的實(shí)現(xiàn)方法,需要的朋友參考下吧2017-02-02

