この項ではAndroid Architecture Componentsを用いた実装例を紹介します。
RFPに対応するViewModelを実装します。
Context
が必要となるので AndroidViewModel
を継承します。
class AdViewModel(app: Application) : AndroidViewModel(app) {
// ...
}
実装したViewModelFactoryからRFP用のViewModelを取得します。
class ArticleFragment : Fragment() {
private lateinit var adViewModel: AdViewModel
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
// ... ...
adViewModel = ViewModelProviders.of(this)
.get(AdViewModel::class.java)
// ... ...
}
}
AdViewModel#getAds()
でLiveDataを返すように実装します。
fun getAds(spotId: String, count: Int, positions: List<Int>?)
: LiveData<AdResponse<List<RFPInstreamInfoModel>>> {
val repository = AdRepository()
return repository.getAds(getApplication(), spotId, count, positions)
}
広告取得の成否を判断するため AdResponse
クラスで広告情報をラップしています。
enum class AdStatus {
SUCCESS,
ERROR,
}
data class AdResponse<out T>(val status: AdStatus, val data: T?, val message: String?) {
companion object {
fun <T> success(data: T?): AdResponse<T> {
return AdResponse(AdStatus.SUCCESS, data, null)
}
fun <T> error(msg: String, data: T?): AdResponse<T> {
return AdResponse(AdStatus.ERROR, data, msg)
}
}
}
LiveDataを購読し、結果をUIに反映します。
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
// ... ...
val positions = listOf(1, 5, 9)
val count = positions.size
adViewModel.getAds(spotId, count, positions).observe(this, Observer { response ->
response ?: return@Observer
if (response.status == AdStatus.ERROR) {
// Failed to fetch ads
return@Observer
}
// Update UI
val ads = response.data ?: return@Observer
// ... ...
})
}
実際の広告取得を行うRepositoryクラスを実装します。
RFPInstreamAdLoader
にリスナーを設定し、onSuccess()
やonFailure()
でLiveDataを変更します。
class AdRepository {
fun getAds(context: Context, spotId: String, count: Int, positions: List<Int>?)
: LiveData<AdResponse<List<RFPInstreamInfoModel>>> {
val data = MutableLiveData<AdResponse<List<RFPInstreamInfoModel>>>()
val loader = RFPInstreamAdLoader.Builder(spotId)
.count(count)
.positions(positions)
.onSuccess { items ->
val response = AdResponse.success(items)
data.postValue(response)
}
.onFailure { message ->
val response = AdResponse.error(message, null)
data.postValue(response)
}
.build()
loader.loadAd(context)
return data
}
}