我正在使用 Retrofit、coroutine、livedata、mvvm 等开发在线购物应用程序
我想在从服务器获取数据几秒钟之前显示进度条
如果我有一个 api 请求,我可以显示这一点,但在这个应用程序中我有多个请求
在这种情况下我应该怎么做我应该如何显示进度条?
API服务
@GET("homeslider.php")
suspend fun getSliderImages(): Response<List<Model.Slider>>
@GET("amazingoffer.php")
suspend fun getAmazingProduct(): Response<List<Model.AmazingProduct>>
@GET("handsImages.php")
suspend fun getHandsFreeData(
@Query(
"handsfree_id"
) handsfree_id: Int
): Response<List<Model.HandsFreeImages>>
@GET("handsfreemoreinfo.php")
suspend fun gethandsfreemoreinfo(): Response<List<Model.HandsFreeMore>>
@GET("wristmetadata.php")
suspend fun getWristWatchMetaData(
@Query(
"wrist_id"
) wrist_id: Int
): Response<List<Model.WristWatch>>
存储库
fun getSliderImages(): LiveData<List<Model.Slider>> {
val data = MutableLiveData<List<Model.Slider>>()
val job = Job()
applicationScope.launch(IO + job) {
val response = api.getSliderImages()
withContext(Main + SupervisorJob(job)) {
data.value = response.body()
}
job.complete()
job.cancel()
}
return data
}
fun getAmazingOffer(): LiveData<List<Model.AmazingProduct>> {
val data = MutableLiveData<List<Model.AmazingProduct>>()
val job = Job()
applicationScope.launch(IO + job) {
val response = api.getAmazingProduct()
withContext(Main + SupervisorJob(job)) {
data.value = response.body()
}
job.complete()
job.cancel()
}
return data
}
fun getHandsFreeData(handsree_id: Int): LiveData<List<Model.HandsFreeImages>> {
val dfData = MutableLiveData<List<Model.HandsFreeImages>>()
val job = Job()
applicationScope.launch(IO + job) {
val response = api.getHandsFreeData(handsree_id)
withContext(Main + SupervisorJob(job)) {
dfData.value = response.body()
}
job.complete()
job.cancel()
}
return dfData
}
fun getHandsFreeMore(): LiveData<List<Model.HandsFreeMore>> {
val data = MutableLiveData<List<Model.HandsFreeMore>>()
val job = Job()
applicationScope.launch(IO + job) {
val response = api.gethandsfreemoreinfo()
withContext(Main + SupervisorJob(job)) {
data.value = response.body()
}
job.complete()
job.cancel()
}
return data
}
View 模型
fun getSliderImages() = repository.getSliderImages()
fun getAmazingOffer() = repository.getAmazingOffer()
fun recieveAdvertise() = repository.recieveAdvertise()
fun dailyShoes(context: Context) = repository.getDailyShoes(context)
我会感谢你的帮助
最佳答案
我忍不住注意到您的存储库包含大量重复代码。这里要了解的第一点是,Repository
中的所有逻辑通常都在 ViewModel
中。第二件事是您正在使用 applicationScope 来启动协程,这通常是使用可用的 viewModelScope(负责取消)对象来完成在每个 viewModel
中。
因此,首先我们必须处理重复的代码并将其移至 ViewModel
。所以你的 viewModel 现在看起来像
class YourViewModel: ViewModel() {
// Your other init code, repo creation etc
// Live data objects for progressBar and error, we will observe these in Fragment/Activity
val showProgress: MutableLiveData<Boolean> = MutableLiveData()
val errorMessage: MutableLiveData<String> = MutableLiveData()
/**
* A Generic api caller, which updates the given live data object with the api result
* and internally takes care of progress bar visibility. */
private fun <T> callApiAndPost(liveData: MutableLiveData<T>,
apiCall: () -> Response<T> ) = viewModelScope.launch {
try{
showProgress.postValue(true) // Show prgress bar when api call is active
if(result.code() == 200) { liveData.postValue(result.body()) }
else{ errorMessage.postValue("Network call failed, try again") }
showProgress.postValue(false)
}
catch (e: Exception){
errorMessage.postValue("Network call failed, try again")
showProgress.postValue(false)
}
}
/******** Now all your API call methods should be called as *************/
// First declare the live data object which will contain the api result
val sliderData: MutableLiveData<List<Model.Slider>> = MutableLiveData()
// Now call the API as
fun getSliderImages() = callApiAndPost(sliderData) {
repository.getSliderImages()
}
}
之后,从存储库
中删除所有逻辑,并使其简单地调用网络方法
suspend fun getSliderImages() = api.getSliderImages() // simply delegate to network layer
最后要显示进度条,只需观察 Activity
中的 showProgress
LiveData
对象/ fragment
为
viewModel.showProgress.observer(this, Observer{
progressBar.visibility = if(it) View.VISIBLE else View.GONE
}
关于java - 使用改造从服务器获取数据之前显示进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68548658/