refactor(frame): 优化基类,添加请求状态的支持

This commit is contained in:
Quyunshuo
2021-07-11 18:12:06 +08:00
parent 7429a02189
commit dddd7f5b54
24 changed files with 183 additions and 208 deletions

View File

@ -1,6 +1,7 @@
package com.quyunshuo.androidbaseframemvvm.base.mvvm.m
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
@ -15,9 +16,12 @@ open class BaseRepository {
/**
* 发起请求封装
* 该方法将flow的执行切换至IO线程
*
* @param requestBlock 请求的整体逻辑
* @return Flow<T>
*/
protected fun <T> flowRequest(requestBlock: suspend FlowCollector<T>.() -> Unit) =
flow(block = requestBlock).flowOn(Dispatchers.IO) // 通过 flowOn 切换到 io 线程
protected fun <T> request(requestBlock: suspend FlowCollector<T>.() -> Unit): Flow<T> {
return flow(block = requestBlock).flowOn(Dispatchers.IO)
}
}

View File

@ -2,8 +2,12 @@ package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter
import com.jaeger.library.StatusBarUtil
import com.quyunshuo.androidbaseframemvvm.base.R
import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.BaseViewModel
import com.quyunshuo.androidbaseframemvvm.base.utils.BindingReflex
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusRegister
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils
@ -15,12 +19,15 @@ import com.quyunshuo.androidbaseframemvvm.base.utils.ViewRecreateHelper
* @author Qu Yunshuo
* @since 8/27/20
*/
abstract class BaseFrameActivity<VB : ViewBinding> : AppCompatActivity(), FrameView<VB> {
abstract class BaseFrameActivity<VB : ViewBinding, VM : BaseViewModel> : AppCompatActivity(),
FrameView<VB> {
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
BindingReflex.reflexViewBinding(javaClass, layoutInflater)
}
protected abstract val mViewModel: VM
/**
* activity页面重建帮助类
*/
@ -35,17 +42,20 @@ abstract class BaseFrameActivity<VB : ViewBinding> : AppCompatActivity(), FrameV
ARouter.getInstance().inject(this)
// 注册EventBus
if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.register(this)
setStatusBar()
mBinding.initView()
initLiveDataObserve()
initObserve()
initRequestData()
}
override fun onDestroy() {
if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.unRegister(
this
)
super.onDestroy()
}
/**
* 设置状态栏
* 子类需要自定义时重写该方法即可
* @return Unit
*/
open fun setStatusBar() {}
override fun isRecreate(): Boolean = mStatusHelper?.isRecreate ?: false
@ -62,6 +72,13 @@ abstract class BaseFrameActivity<VB : ViewBinding> : AppCompatActivity(), FrameV
/**
* - activity 重建帮助工具类
*/
private class ActivityRecreateHelper(savedInstanceState: Bundle? = null) : ViewRecreateHelper(savedInstanceState)
private class ActivityRecreateHelper(savedInstanceState: Bundle? = null) :
ViewRecreateHelper(savedInstanceState)
override fun onDestroy() {
if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.unRegister(
this
)
super.onDestroy()
}
}

View File

@ -7,6 +7,7 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter
import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.BaseViewModel
import com.quyunshuo.androidbaseframemvvm.base.utils.BindingReflex
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusRegister
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils
@ -18,12 +19,14 @@ import com.quyunshuo.androidbaseframemvvm.base.utils.ViewRecreateHelper
* @author Qu Yunshuo
* @since 8/27/20
*/
abstract class BaseFrameFragment<VB : ViewBinding> : Fragment(), FrameView<VB> {
abstract class BaseFrameFragment<VB : ViewBinding, VM : BaseViewModel> : Fragment(), FrameView<VB> {
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
BindingReflex.reflexViewBinding(javaClass, layoutInflater)
}
protected abstract val mViewModel: VM
/**
* fragment状态保存工具类
*/
@ -45,8 +48,9 @@ abstract class BaseFrameFragment<VB : ViewBinding> : Fragment(), FrameView<VB> {
ARouter.getInstance().inject(this)
// 注册EventBus
if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.register(this)
mBinding.initView()
initLiveDataObserve()
initObserve()
initRequestData()
}
@ -65,16 +69,17 @@ abstract class BaseFrameFragment<VB : ViewBinding> : Fragment(), FrameView<VB> {
super.onSaveInstanceState(outState)
}
/**
* - fragment状态保存帮助类
* - 暂时没有其他需要保存的--空继承
*/
private class FragmentStatusHelper(savedInstanceState: Bundle? = null) :
ViewRecreateHelper(savedInstanceState)
override fun onDestroy() {
if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.unRegister(
this
)
super.onDestroy()
}
/**
* - fragment状态保存帮助类
* - 暂时没有其他需要保存的--空继承
*/
private class FragmentStatusHelper(savedInstanceState: Bundle? = null) : ViewRecreateHelper(savedInstanceState)
}

View File

@ -1,40 +0,0 @@
package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter
import com.quyunshuo.androidbaseframemvvm.base.utils.BindingReflex
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusRegister
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils
/**
* 不使用 MVVM 的 Activity 基类
*
* @author Qu Yunshuo
* @since /9/10/20
*/
abstract class BaseFrameNotMVVMActivity<VB : ViewBinding> : AppCompatActivity(),
FrameNotMVVMView<VB> {
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
BindingReflex.reflexViewBinding(javaClass, layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(mBinding.root)
// ARouter 依赖注入
ARouter.getInstance().inject(this)
// 注册EventBus
if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.register(this)
mBinding.initView()
}
override fun onDestroy() {
if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.unRegister(
this
)
super.onDestroy()
}
}

View File

@ -1,49 +0,0 @@
package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter
import com.quyunshuo.androidbaseframemvvm.base.utils.BindingReflex
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusRegister
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils
/**
* 不使用 MVVM 的 Fragment 基类
*
* @author Qu Yunshuo
* @since 9/10/20
*/
abstract class BaseFrameNotMVVMFragment<VB : ViewBinding> : Fragment(), FrameNotMVVMView<VB> {
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
BindingReflex.reflexViewBinding(javaClass, layoutInflater)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return mBinding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// ARouter 依赖注入
ARouter.getInstance().inject(this)
// 注册EventBus
if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.register(this)
mBinding.initView()
}
override fun onDestroy() {
if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.unRegister(
this
)
super.onDestroy()
}
}

View File

@ -1,16 +0,0 @@
package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
import androidx.viewbinding.ViewBinding
/**
* View层基类抽象
*
* @author Qu Yunshuo
* @since 10/13/20
*/
interface FrameNotMVVMView<VB : ViewBinding> {
/**
* 初始化View
*/
fun VB.initView()
}

View File

@ -9,18 +9,19 @@ import androidx.viewbinding.ViewBinding
* @since 10/13/20
*/
interface FrameView<VB : ViewBinding> {
/**
* 初始化View
*/
fun VB.initView()
/**
* 初始化LiveData的订阅关系
* 订阅LiveData
*/
fun initLiveDataObserve()
fun initObserve()
/**
* 初始化界面创建时的数据请求,尝试在此方法内调用[isRecreate]进行重建判断,防止数据重复获取
* 用于在页面创建时进行请求接口
*/
fun initRequestData()

View File

@ -2,6 +2,8 @@ package com.quyunshuo.androidbaseframemvvm.base.mvvm.vm
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.quyunshuo.androidbaseframemvvm.base.utils.StateLayoutEnum
import kotlin.jvm.Throws
/**
* ViewModel 基类
@ -11,9 +13,45 @@ import androidx.lifecycle.ViewModel
*/
abstract class BaseViewModel : ViewModel() {
// Loading 状态
val isLoading = MutableLiveData(false)
/**
* 控制状态视图的LiveData
*/
val stateViewLD = MutableLiveData<StateLayoutEnum>()
// 请求异常
val requestError = MutableLiveData<Throwable?>()
/**
* 更改状态视图的状态
*
* @param hide Boolean 是否进行隐藏状态视图
* @param loading Boolean 是否显示加载中视图
* @param error Boolean 是否显示错误视图
* @param noData Boolean 是否显示没有数据视图
* @return Unit
* @throws IllegalArgumentException 如果入参没有传入任何参数或者为true的参数 >1 时,会抛出[IllegalArgumentException]
*/
@Throws(IllegalArgumentException::class)
protected fun changeStateView(
hide: Boolean = false,
loading: Boolean = false,
error: Boolean = false,
noData: Boolean = false
) {
// 对参数进行校验
var count = 0
if (hide) count++
if (loading) count++
if (error) count++
if (noData) count++
when {
count == 0 -> throw IllegalArgumentException("必须设置一个参数为true")
count > 1 -> throw IllegalArgumentException("只能有一个参数为true")
}
// 修改状态
when {
hide -> stateViewLD.postValue(StateLayoutEnum.HIDE)
loading -> stateViewLD.postValue(StateLayoutEnum.LOADING)
error -> stateViewLD.postValue(StateLayoutEnum.ERROR)
noData -> stateViewLD.postValue(StateLayoutEnum.NO_DATA)
}
}
}

View File

@ -0,0 +1,13 @@
package com.quyunshuo.androidbaseframemvvm.base.mvvm.vm
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
/**
* 空的ViewModel 主要给现阶段不需要ViewModel的界面使用
*
* @author Qu Yunshuo
* @since 2021/7/10 11:04 上午
*/
@HiltViewModel
class EmptyViewModel @Inject constructor() : BaseViewModel()

View File

@ -0,0 +1,14 @@
package com.quyunshuo.androidbaseframemvvm.base.utils
/**
* 状态视图的状态枚举
*
* @author Qu Yunshuo
* @since 2021/7/10 9:16 上午
*/
enum class StateLayoutEnum {
HIDE, // 隐藏
LOADING, // 加载中
ERROR, // 错误
NO_DATA // 没有数据
}