打造流暢自動加載分頁的Github API Demo:MVVM、DI、RxJava與Paging在Android Kotlin的實踐教學

前言

今天我要分享的是使用以下架構,
來串接Github API來實作流暢自動加載分頁的範例。
1.透過mvvm架構
2.RxJava控制網路請求
3.dependency injection
4.使用paging來呈現recycler view 分頁
5.資料串接github api

最後實際出來的畫面長這樣:


使用的是api的是Github提供的/search/users


curl \
  -H "Accept: application/vnd.github.v3+json" \
  https://api.github.com/search/users
實現的功能是


在搜尋欄位輸入搜尋文字
透過建好的data class去打API 並依照指定數量顯示出返回的結果

前期架構思想(TL;DR)

首先 開始必需規劃架構
這邊使用的是mvvm為主
心中會先有大概的圖譜
但不會一開始就全部用出來
會先一層一層架
這邊是我簡略的範例:


預想開發步驟


1.首先,我們先著手處理一些基本的共用類別,
例如 base 資料夾、Android Application 以及基本的 XML 配置等等。
這些類別在後續的開發中可能會被多次使用,
因此我們先完成這些基礎建設的工作。

2-a.這次決定使用 Jetpack ViewModel 和 Dagger2。
開發 DI 資料夾主要針對 Application 做 component,
裡面是其他模組可以使用的一些共用方法,
例如提供 Application / Context 或提供新的共用方法等等。

2-b.在開始建構 HTTP 模組前,
我已經想好要使用哪些 Library,
包括 OkHttp、Retrofit 和 RxJava。
接著我開始建構 HTTP 模組,
實作了 Retrofit client,
主要是為了提供 Retrofit 實例,像這樣:

之後就裝進HttpModule提供給未來其他頁面的module用

3.開始建構頁面的component 與 module
前面所需的基本類別都建好後
就可以開始建立新的 module 來實作主要功能
這裡可以搭配寫好的 HttpModule,只需要再寫一些對外打 request 的 API 即可。

4.開始建構 viewmodel 與 repository 相關的部分,
思考之後需要哪些資料以及如何更新資料來制訂你的 viewmodel,
再搭配 repository 來執行 http request。

建好上述功能後,
回到module中新增需要提供給di自動注入的類。

5.前面的準備工作都完成後,現在可以開始撰寫畫面了。
使用Navigation Graph配置Activity與Fragment,
並將之前建立的DI類別注入到要執行的Activity或Fragment中,
讓它們可以使用DI的功能。

以上是這次預先思考整個開發流程的思想
到這,
才是真正開始談怎麼寫程式碼!
之前的部分只是我的一些經驗分享和建議,
現在讓我們正式進入主題。

實作開始
建一些基本類


像BaseApplicaiont , Constants , BaseActivity..等等
用意是設計一些通用的程式碼
一些常用需要init的東西寫在這
也能讓你主要那個applicaion / BaseActivity 類看起來程式碼更少 更好讀 或之後少寫code


主要架構

a.先開發application相關di的component與module

先把基本的di module建出來


component建出來 :

b. 開發http請求用的module

再開發http的連線模組
因為想到後面app可能是以http連線為主
所以先架http module
http module長這樣:

RetrofitClient是我自行封裝的類,br> 返回一個Retrofit
中間透過builder 與自製okhttp builder
去建製這個Retrofit實例

因後續會用到Rxjava的Observable
所以在建置的時候先加入
RxJava2CallAdapterFactory

.addCallAdapterFactory(RxJava2CallAdapterFactory.create())

讓retrofit能支持Rxjava


開發功能

c-1.建立 Retrofit 用的 API interface

c-2.建立 Reposity 到時候實際呼叫api的地方

c-3.建立 viewmodel 並預想到時候有哪些資料要觀察變化的

以本例來看的話
就是以下需要觀察資料變化
1.ui顯示狀態
2.paging時要顯示的list資料

c-4.建立module

這邊的@Provides | @Moduel | @Inject 是DI需加的一些Annotations
所以根據不同情況或地方 需加入相關Annotations

c-5.加入http module

前面寫的http module 派上用場了
在你要調用的module前面加入下方code

@Module(includes = [HttpModule::class])

c-6.建立顯示畫面的fragment

開始建立fragment並注入viewmodel

c-7.建立欲使用的module

這裡是一個建立 Dagger Component 的步驟
1.寫一個component
2.如果需要使用到 context,則可以導入之前建立的 app component
3.加入欲使用的 module

c-8. 刻app的view

剩下就是要開始去刻app的view與分頁功能了

我這邊則是用android官方paging去做分頁
用recycler view 搭配 paging library

首先寫一個class PagedListAdapter
接著建立 getItemViewType、onBindViewHolder、onCreateViewHolder:
建立DiffUtil.ItemCallback 用來判斷新的資料與舊的資料差異
不同的話就會更新

再來建立 pageing會用到的DataSource.Factory
這段是關於PageKeyedDataSource的使用,
該類別內有三個override method,
裡面有 loadInitial、loadAfter、loadBefore等override method
可以分別代表初始化時、讀到資料前、後

透過自定義資料加入pagelist內,
你可以在這幾個method內實現你的業務邏輯,
例如在初始化時去執行http request。

例如製作一個onResult callback interface
當實際遇到loadAfter時再call此方法
來把資料傳回呼叫點

callback.onResult(listSearchUser, initPage, nextKey)

當然這邊的方法怎麼寫
可以根據各自情況調整
出來的結果也可能不同

這是我的範例:

You might also enjoy