From 5fa5f680a92d18bfec70ff5ec7061da6b25c78f4 Mon Sep 17 00:00:00 2001 From: leavesC <1990724437@qq.com> Date: Wed, 1 Dec 2021 23:28:09 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=B7=BB=E5=8A=A0=20ReactiveFragment?= =?UTF-8?q?=20=E7=A4=BA=E4=BE=8B=202=E3=80=81=E7=A7=BB=E9=99=A4=E5=86=97?= =?UTF-8?q?=E4=BD=99=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reactivehttp/base/ReactiveActivity.kt | 7 +- .../reactivehttp/base/ReactiveFragment.kt | 96 +++++++++++++++++++ .../viewmodel/UIActionEventObserver.kt | 39 ++++---- 3 files changed, 118 insertions(+), 24 deletions(-) create mode 100644 reactivehttp/src/main/java/github/leavesc/reactivehttp/base/ReactiveFragment.kt diff --git a/reactivehttp/src/main/java/github/leavesc/reactivehttp/base/ReactiveActivity.kt b/reactivehttp/src/main/java/github/leavesc/reactivehttp/base/ReactiveActivity.kt index 0cf07b0..21caaf8 100644 --- a/reactivehttp/src/main/java/github/leavesc/reactivehttp/base/ReactiveActivity.kt +++ b/reactivehttp/src/main/java/github/leavesc/reactivehttp/base/ReactiveActivity.kt @@ -7,6 +7,7 @@ import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope +import github.leavesc.reactivehttp.viewmodel.IUIAction import github.leavesc.reactivehttp.viewmodel.IUIActionEventObserver import kotlinx.coroutines.CoroutineScope @@ -21,9 +22,10 @@ open class ReactiveActivity : AppCompatActivity(), IUIActionEventObserver { protected inline fun getViewModel( factory: ViewModelProvider.Factory? = null, noinline initializer: (VM.(lifecycleOwner: LifecycleOwner) -> Unit)? = null - ): Lazy where VM : ViewModel { + ): Lazy where VM : ViewModel, VM : IUIAction { return lazy { getViewModelFast( + viewModelStoreOwner = this, lifecycleOwner = this, viewModelClass = VM::class.java, factory = factory, @@ -35,9 +37,10 @@ open class ReactiveActivity : AppCompatActivity(), IUIActionEventObserver { protected inline fun getViewModelInstance( crossinline create: () -> VM, noinline initializer: (VM.(lifecycleOwner: LifecycleOwner) -> Unit)? = null - ): Lazy where VM : ViewModel { + ): Lazy where VM : ViewModel, VM : IUIAction { return lazy { getViewModelFast( + viewModelStoreOwner = this, lifecycleOwner = this, viewModelClass = VM::class.java, factory = object : ViewModelProvider.NewInstanceFactory() { diff --git a/reactivehttp/src/main/java/github/leavesc/reactivehttp/base/ReactiveFragment.kt b/reactivehttp/src/main/java/github/leavesc/reactivehttp/base/ReactiveFragment.kt new file mode 100644 index 0000000..e14b81c --- /dev/null +++ b/reactivehttp/src/main/java/github/leavesc/reactivehttp/base/ReactiveFragment.kt @@ -0,0 +1,96 @@ +package github.leavesc.reactivehttp.base + +import android.app.ProgressDialog +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope +import github.leavesc.reactivehttp.viewmodel.IUIAction +import github.leavesc.reactivehttp.viewmodel.IUIActionEventObserver +import kotlinx.coroutines.CoroutineScope + +/** + * @Author: leavesC + * @Date: 2021/12/1 23:16 + * @Desc: + * @Github:https://github.com/leavesC + */ +class ReactiveFragment : Fragment(), IUIActionEventObserver { + + protected inline fun getViewModel( + lifecycleOwner: LifecycleOwner = viewLifecycleOwner, + factory: ViewModelProvider.Factory? = null, + noinline initializer: (VM.(lifecycleOwner: LifecycleOwner) -> Unit)? = null + ): Lazy where VM : ViewModel, VM : IUIAction { + return lazy { + getViewModelFast( + viewModelStoreOwner = this, + lifecycleOwner = lifecycleOwner, + viewModelClass = VM::class.java, + factory = factory, + initializer = initializer + ) + } + } + + protected inline fun getViewModelInstance( + lifecycleOwner: LifecycleOwner = viewLifecycleOwner, + crossinline create: () -> VM, + noinline initializer: (VM.(lifecycleOwner: LifecycleOwner) -> Unit)? = null + ): Lazy where VM : ViewModel, VM : IUIAction { + return lazy { + getViewModelFast( + viewModelStoreOwner = this, + lifecycleOwner = lifecycleOwner, + viewModelClass = VM::class.java, + factory = object : ViewModelProvider.NewInstanceFactory() { + override fun create(modelClass: Class): T { + return create() as T + } + }, + initializer = initializer + ) + } + } + + override val lifecycleSupportedScope: CoroutineScope + get() = viewLifecycleOwner.lifecycleScope + + private var loadDialog: ProgressDialog? = null + + override fun showLoading() { + dismissLoading() + activity?.let { act -> + loadDialog = ProgressDialog(act).apply { + setCancelable(true) + setCanceledOnTouchOutside(false) + show() + } + } + } + + override fun dismissLoading() { + loadDialog?.takeIf { it.isShowing }?.dismiss() + loadDialog = null + } + + override fun showToast(msg: String) { + activity?.let { act -> + if (msg.isNotBlank()) { + Toast.makeText(act, msg, Toast.LENGTH_SHORT).show() + } + } + } + + override fun finishView() { + activity?.finish() + } + + override fun onDestroyView() { + super.onDestroyView() + dismissLoading() + } + +} \ No newline at end of file diff --git a/reactivehttp/src/main/java/github/leavesc/reactivehttp/viewmodel/UIActionEventObserver.kt b/reactivehttp/src/main/java/github/leavesc/reactivehttp/viewmodel/UIActionEventObserver.kt index a118fc6..513208a 100644 --- a/reactivehttp/src/main/java/github/leavesc/reactivehttp/viewmodel/UIActionEventObserver.kt +++ b/reactivehttp/src/main/java/github/leavesc/reactivehttp/viewmodel/UIActionEventObserver.kt @@ -56,42 +56,37 @@ interface IUIActionEventObserver { fun finishView() + /** + * 用于方便获取 ViewModel 实例 + * 重点在于调用了 collectUiActionIfNeed 方法 + * 启动了协程对 uiActionEventFlow 进行监听 + */ fun getViewModelFast( + viewModelStoreOwner: ViewModelStoreOwner, lifecycleOwner: LifecycleOwner, viewModelClass: Class, factory: ViewModelProvider.Factory? = null, initializer: (VM.(lifecycleOwner: LifecycleOwner) -> Unit)? = null - ): VM where VM : ViewModel { - return when (lifecycleOwner) { - is ViewModelStoreOwner -> { - if (factory == null) { - ViewModelProvider(lifecycleOwner).get(viewModelClass) - } else { - ViewModelProvider(lifecycleOwner, factory).get(viewModelClass) - } - } - else -> { - factory?.create(viewModelClass) ?: viewModelClass.newInstance() - } + ): VM where VM : ViewModel, VM : IUIAction { + return if (factory == null) { + ViewModelProvider(viewModelStoreOwner).get(viewModelClass) + } else { + ViewModelProvider(viewModelStoreOwner, factory).get(viewModelClass) }.apply { - applyExtraAction(lifecycleOwner = lifecycleOwner, viewModel = this) - collectUiActionIfNeed(lifecycleOwner = lifecycleOwner, viewModel = this) initializer?.invoke(this, lifecycleOwner) + collectUiActionIfNeed(viewModel = this) } } /** - * 外部可以通过此方法来为 ViewModel 增加一些额外操作 + * 如果外部不通过 getViewModelFast 方法来获取 ViewModel 实例的话 + * 则必须在自己构建 ViewModel 实例后调用 collectUiActionIfNeed 方法 + * 以便能够启动协程对 uiActionEventFlow 进行监听 */ - fun applyExtraAction(lifecycleOwner: LifecycleOwner, viewModel: ViewModel) { - - } - fun collectUiActionIfNeed( - lifecycleOwner: LifecycleOwner, viewModel: VM - ) where VM : ViewModel { - val uiActionEventFlow = (viewModel as? IUIAction)?.uiActionEventFlow + ) where VM : ViewModel, VM : IUIAction { + val uiActionEventFlow = viewModel.uiActionEventFlow if (uiActionEventFlow != null) { lifecycleSupportedScope.launch(Dispatchers.Main.immediate) { uiActionEventFlow.collect {