[英]How to show a LoadingDialog only if the operation takes too long?
我在我的 Android 應用程序中進行API
調用,它幾乎可以立即返回響應或需要更長的時間,在API
調用之前我顯示我的LoadingDialog
並在響應時我將其關閉,最大的問題是即使響應是即時的我顯示和關閉LoadingDialog
,它看起來像一個“錯誤”,因為屏幕立即顯示和隱藏了一個對話框。
只有當響應的返回時間超過 1 秒時,我才能顯示該對話框。
這是我的代碼:
public void AlertLoading() {
Fragment fragment = getSupportFragmentManager().findFragmentByTag(LoadingDialog.TAG);
if (fragment instanceof LoadingDialog) {
((LoadingDialog) fragment).dismissAllowingStateLoss();
}else {
new LoadingDialog().show(getSupportFragmentManager(), LoadingDialog.TAG);
}
}
private void getTable(String tableNumber) {
AlertLoading();
Ion.with(getApplicationContext())
.load("http://" + ip + "/webquery/?FINDTAV=" + tableNumber + "&v2=true")
.setTimeout(10000)
.asString()
.setCallback((e, result) -> {
AlertLoading();
// DOING STUFF
});
}
使用 Flows 接收 api 響應並在協程中收集它
viewModelScope.launch(Dispatchers.IO) {
repo.myApiFunc(param1, param2)
.onStart {
withContext(Dispatchers.Main) {
uiState.value = UiState.ProgressBar(true)
}
}
.catch {
withContext(Dispatchers.Main) {
uiState.value = UiState.ProgressBar(false)
}
}
.collect { response->
withContext(Dispatchers.Main) {
uiState.value = UiState.ProgressBar(false)
handleData(response)
}
}
}
你的存儲庫功能看起來像這樣
suspend fun myApiFunc(param1: Any, param2: Any
): Flow<MyResponse> {
return flow<MyResponse> {
emit(apiHelper.apiCall(param1, param2))
}
}
在你的 api 調用中看起來像
@POST("Endpoint")
suspend fun apiCall(
@Field("email") email: String,
@Field("password") password: String
): MyResponse
並且您的 uistate 變量也是在片段內收集的流類型,並在接收到 true 時顯示加載器,而在 false 時隱藏它
正如@Ricky Mo 在評論中所建議的那樣,我遵循了檢查 Content-Lenght 的方法,如果這大於 X 字節,我將顯示加載對話框。
我將代碼更改如下:
private void getTable(String tableNumber) {
// Doing an API call with HEAD method which returns Content-Lenght, if this is > than 10000 i'm showing the dialog
LoadingDialog.RetrofitClient.getInstance(ip).getApi().getTableLenght(tableNumber, true)
.enqueue(new Callback<Void>() {
@Override
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
String contentLength = response.headers().get("Content-Length");
if (contentLength != null) {
if (Double.parseDouble(contentLength) > 10000) {
showLoading(true);
}
}
}
@Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
showLoading(false);
}
});
// I've changed Ion with Retrofit for data parsing
Call<String> call = RetrofitClient.getInstance(ip).getApi().getTable(tableNumber, true);
call.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
showLoading(false);
if (response.isSuccessful()) {
... Doing stuff
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
showLoading(false);
}
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.