From 260f6a8de520d42510a124b038837017ba845894 Mon Sep 17 00:00:00 2001 From: Ztiany Date: Wed, 16 Oct 2019 20:02:56 +0800 Subject: [PATCH] enhance dialog --- .../main/java/com/android/base/app/Sword.java | 19 +++++++++- .../base/app/aac/LiveResourceHandler.kt | 35 ++++++++++++++--- .../base/app/fragment/BaseDialogFragment.kt | 15 ++++++++ .../android/base/app/fragment/BaseFragment.kt | 14 +++++++ .../com/android/base/app/fragment/utils.kt | 38 +++++++++++++++++++ .../com/android/base/app/ui/LoadingView.kt | 3 ++ 6 files changed, 117 insertions(+), 7 deletions(-) create mode 100644 lib_base/src/main/java/com/android/base/app/fragment/utils.kt diff --git a/lib_base/src/main/java/com/android/base/app/Sword.java b/lib_base/src/main/java/com/android/base/app/Sword.java index 01f82a9..3b38a58 100644 --- a/lib_base/src/main/java/com/android/base/app/Sword.java +++ b/lib_base/src/main/java/com/android/base/app/Sword.java @@ -63,6 +63,11 @@ public final class Sword { */ private ErrorClassifier mErrorClassifier; + /** + * dialog 最小展示时间 + */ + private long minimumShowingDialogMills; + /** * 获取 Application 代理 */ @@ -110,7 +115,7 @@ public final class Sword { } /** - * 给 {@link com.android.base.app.fragment.Fragments } 设置一个默认的容器 id,在使用 其相关方法而没有传入特定的容器 id 时,则使用默认的容器 id。 + * 给 {@link com.android.base.app.fragment.tools.Fragments } 设置一个默认的容器 id,在使用 其相关方法而没有传入特定的容器 id 时,则使用默认的容器 id。 * * @param defaultContainerId 容器id */ @@ -119,6 +124,14 @@ public final class Sword { return this; } + /** + * 设置 dialog 最小展示时间,建议不超过 1 秒 + */ + public Sword setMinimumShowingDialogMills(long minimumShowingDialogMills) { + this.minimumShowingDialogMills = minimumShowingDialogMills; + return this; + } + public Sword setDefaultFragmentAnimator(FragmentAnimator animator) { FragmentConfig.setDefaultFragmentAnimator(animator); return this; @@ -210,4 +223,8 @@ public final class Sword { return this; } + public long minimumShowingDialogMills() { + return minimumShowingDialogMills; + } + } \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/app/aac/LiveResourceHandler.kt b/lib_base/src/main/java/com/android/base/app/aac/LiveResourceHandler.kt index db49005..b45bfac 100644 --- a/lib_base/src/main/java/com/android/base/app/aac/LiveResourceHandler.kt +++ b/lib_base/src/main/java/com/android/base/app/aac/LiveResourceHandler.kt @@ -3,6 +3,7 @@ package com.android.base.app.aac import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LiveData import androidx.lifecycle.Observer +import com.android.base.app.Sword import com.android.base.app.ui.LoadingView import com.android.base.data.Resource import timber.log.Timber @@ -34,8 +35,17 @@ fun H.handleLiveResource( } it.isSuccess -> { Timber.d("handleLiveResource -> isSuccess") - dismissLoadingDialog() - onSuccess(it.get()) + val minimumShowingDialogMills = Sword.get().minimumShowingDialogMills() + + if (minimumShowingDialogMills == 0L) { + dismissLoadingDialog() + onSuccess(it.get()) + } else { + dismissLoadingDialog(minimumShowingDialogMills) { + onSuccess(it.get()) + } + } + } } }) @@ -62,11 +72,24 @@ fun H.handleLiveResourceWithData( } it.isSuccess -> { Timber.d("handleLiveResourceWithData -> isSuccess") - dismissLoadingDialog() - if (it.hasData()) { - onSuccess(it.data()) + + val minimumShowingDialogMills = Sword.get().minimumShowingDialogMills() + + if (minimumShowingDialogMills == 0L) { + dismissLoadingDialog() + if (it.hasData()) { + onSuccess(it.data()) + } else { + onEmpty?.invoke() + } } else { - onEmpty?.invoke() + dismissLoadingDialog(minimumShowingDialogMills) { + if (it.hasData()) { + onSuccess(it.data()) + } else { + onEmpty?.invoke() + } + } } } } diff --git a/lib_base/src/main/java/com/android/base/app/fragment/BaseDialogFragment.kt b/lib_base/src/main/java/com/android/base/app/fragment/BaseDialogFragment.kt index 9ac772d..c7f0571 100644 --- a/lib_base/src/main/java/com/android/base/app/fragment/BaseDialogFragment.kt +++ b/lib_base/src/main/java/com/android/base/app/fragment/BaseDialogFragment.kt @@ -37,6 +37,8 @@ open class BaseDialogFragment : AppCompatDialogFragment(), LoadingView, OnBackPr @Suppress("LeakingThis") private val fragmentDelegates = FragmentDelegates(this) + private var recentShowingDialogTime: Long = 0 + private fun tag() = this.javaClass.simpleName override fun onAttach(context: Context) { @@ -220,19 +222,24 @@ open class BaseDialogFragment : AppCompatDialogFragment(), LoadingView, OnBackPr return null } + override fun showLoadingDialog() { + recentShowingDialogTime = System.currentTimeMillis() loadingView().showLoadingDialog(true) } override fun showLoadingDialog(cancelable: Boolean) { + recentShowingDialogTime = System.currentTimeMillis() loadingView().showLoadingDialog(cancelable) } override fun showLoadingDialog(message: CharSequence, cancelable: Boolean) { + recentShowingDialogTime = System.currentTimeMillis() loadingView().showLoadingDialog(message, cancelable) } override fun showLoadingDialog(@StringRes messageId: Int, cancelable: Boolean) { + recentShowingDialogTime = System.currentTimeMillis() loadingView().showLoadingDialog(messageId, cancelable) } @@ -240,6 +247,14 @@ open class BaseDialogFragment : AppCompatDialogFragment(), LoadingView, OnBackPr loadingView().dismissLoadingDialog() } + override fun dismissLoadingDialog(minimumMills: Long, onDismiss: () -> Unit) { + dismissDialog(recentShowingDialogTime, minimumMills, onDismiss) + } + + override fun isLoadingDialogShowing(): Boolean { + return loadingView().isLoadingDialogShowing() + } + override fun showMessage(message: CharSequence) { loadingView().showMessage(message) } diff --git a/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt b/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt index 870a0da..2ea9206 100644 --- a/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt +++ b/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt @@ -48,6 +48,8 @@ open class BaseFragment : Fragment(), LoadingView, OnBackPressListener, Fragment @Suppress("LeakingThis") private val fragmentDelegates = FragmentDelegates(this) + private var recentShowingDialogTime: Long = 0 + private fun tag() = this.javaClass.simpleName override fun onAttach(context: Context) { @@ -232,18 +234,22 @@ open class BaseFragment : Fragment(), LoadingView, OnBackPressListener, Fragment } override fun showLoadingDialog() { + recentShowingDialogTime = System.currentTimeMillis() loadingView().showLoadingDialog(true) } override fun showLoadingDialog(cancelable: Boolean) { + recentShowingDialogTime = System.currentTimeMillis() loadingView().showLoadingDialog(cancelable) } override fun showLoadingDialog(message: CharSequence, cancelable: Boolean) { + recentShowingDialogTime = System.currentTimeMillis() loadingView().showLoadingDialog(message, cancelable) } override fun showLoadingDialog(@StringRes messageId: Int, cancelable: Boolean) { + recentShowingDialogTime = System.currentTimeMillis() loadingView().showLoadingDialog(messageId, cancelable) } @@ -251,6 +257,14 @@ open class BaseFragment : Fragment(), LoadingView, OnBackPressListener, Fragment loadingView().dismissLoadingDialog() } + override fun dismissLoadingDialog(minimumMills: Long, onDismiss: () -> Unit) { + dismissDialog(recentShowingDialogTime, minimumMills, onDismiss) + } + + override fun isLoadingDialogShowing(): Boolean { + return loadingView().isLoadingDialogShowing() + } + override fun showMessage(message: CharSequence) { loadingView().showMessage(message) } diff --git a/lib_base/src/main/java/com/android/base/app/fragment/utils.kt b/lib_base/src/main/java/com/android/base/app/fragment/utils.kt new file mode 100644 index 0000000..9e595ef --- /dev/null +++ b/lib_base/src/main/java/com/android/base/app/fragment/utils.kt @@ -0,0 +1,38 @@ +package com.android.base.app.fragment + +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.lifecycleScope +import com.android.base.app.ui.LoadingView +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + +/** + *@author Ztiany + * Email: ztiany3@gmail.com + * Date : 2019-10-16 17:28 + */ +internal fun T.dismissDialog(recentShowingDialogTime: Long, minimumMills: Long, onDismiss: () -> Unit) where T : LoadingView, T : LifecycleOwner { + + if (!isLoadingDialogShowing()) { + onDismiss() + return + } + + val dialogShowingTime = System.currentTimeMillis() - recentShowingDialogTime + + if (dialogShowingTime >= minimumMills) { + onDismiss() + } else { + lifecycleScope.launch { + try { + delay(minimumMills - dialogShowingTime) + dismissLoadingDialog() + onDismiss() + } catch (e: CancellationException) { + onDismiss() + } + } + } + +} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/app/ui/LoadingView.kt b/lib_base/src/main/java/com/android/base/app/ui/LoadingView.kt index 8aed40b..e6dcb1d 100644 --- a/lib_base/src/main/java/com/android/base/app/ui/LoadingView.kt +++ b/lib_base/src/main/java/com/android/base/app/ui/LoadingView.kt @@ -16,6 +16,9 @@ interface LoadingView { fun showLoadingDialog(message: CharSequence, cancelable: Boolean) fun showLoadingDialog(@StringRes messageId: Int, cancelable: Boolean) fun dismissLoadingDialog() + fun dismissLoadingDialog(minimumMills: Long, onDismiss: () -> Unit) + fun isLoadingDialogShowing(): Boolean + fun showMessage(message: CharSequence) fun showMessage(@StringRes messageId: Int)