• MVVM的构建(java&kotlin)


    概念性的描述就不写了,直接上代码

    MVVM框架,主要是构建基类,实现ViewModel绑定,ViewBinding的绑定,在构建好基类后,后续开发中新建activity或fragment的viewModel和viewBinding就会在基类的方法中实现绑定

    1.新建一个抽象类Repository,仓库类,网络请求或者从本都读取缓存都仓库类的实现类中处理

     2.新建一个BaseViewModel抽象类,继承自ViewModel,如果要在viewModel中使用Application,那么就继承AndroidViewModel,因为AndroidViewModel的构造函数中,必须传入一个Application

     我这里选择了传入了一个BaseRepository的对象,也就是对应的仓库,从仓库中获取数据,在ViewModel中使用liveData

    3.1.创建fragment绑定ViewBinding的抽象类,在这个类中获取每个fragment的xml文件的DataBinding

     3.2.创建一个抽象BaseFragment类,继承ViewBindingFragment,并且在BaseFragment类中实现ViewModel的绑定

     

      4.1.同上,创建一个ViewBindingActivity的抽象类,作用也是获取activity xml的viewBinding

         

     4.2.创建一个BaseActivity的抽象类,继承ViewBindingActivity,作用就是在BaseActivity中绑定ViewModel

     

     使用就很简单了,如果你的fragment中不涉及到数据请求获取,不需要创建ViewModel,那么直接继承ViewBingFragment,这样省的要在fragment中对xml里面的空间id进行findViewById,也能实现数据双向绑定,如果涉及到数据请求,那么就继承BaseFragment,创建一个当前fragment对应的viewModel,利用liveData的特性,在fragment中,只需要注册liveData的观察者就能接收到数据的更新

    ---------------------------------------------------------------------------------------------------------------------------------

    kotlin版本的mvvm,其实思路写法和java版本的一样,只是一些语法的不同

    1.创建ViewModel基类

    2.在java版本中,我们是先实现dataBinding,在kotlin中我们先来实现ViewModel的绑定

    1. /**
    2. * 带databinding和BaseViewModel的fragment
    3. * dataBinding就是各个fragment自己布局的binding
    4. * VM就是给每个fragment创建的ViewModel
    5. * 其实这个类,就是相当于抽象工厂模式,封装了构造ViewModel的方法
    6. */
    7. abstract class ViewModelFragment<V : ViewBinding, VM : BaseViewModel<BaseModel>> : Fragment() {
    8. private val TAG = javaClass.simpleName
    9. protected lateinit var mViewBinding: V
    10. protected lateinit var mViewModel: VM
    11. //定义一个获取dataBinding的抽象函数,子类可重写此函数,构造dataBinding
    12. abstract fun initBinding(inflater: LayoutInflater, container: ViewGroup?): V
    13. /**
    14. * 每个视图,都要持有一个ViewModel
    15. * 这里是给每个视图绑定viewModel
    16. * 将子类的ViewModel传进来绑定ViewModel
    17. */
    18. @Suppress("UNCHECKED_CAST")
    19. fun initViewModel(viewModelStoreOwner: ViewModelStoreOwner): VM {
    20. var modelClass: Class<VM>?;
    21. val type: Type? = javaClass.genericSuperclass
    22. modelClass = if (type is ParameterizedType) {
    23. type.actualTypeArguments[1] as Class<VM>
    24. } else {
    25. null
    26. }
    27. if (modelClass == null) {
    28. modelClass = BaseModel::class.java as Class<VM>
    29. }
    30. //最终目的就是创建ViewModel,绑定了ViewModel的生命周期,也就是在这里,viewModel持有了lifecycle的对象
    31. return ViewModelProvider(
    32. viewModelStoreOwner,
    33. ViewModelProvider.AndroidViewModelFactory(BaseApplication.getInstance())
    34. )[modelClass]
    35. }
    36. /**
    37. * 绑定ViewModel
    38. */
    39. fun <T:ViewModel> obtainViewModel(viewModelClass : Class<T>)=
    40. ViewModelProvider(
    41. viewModelStore,
    42. ViewModelProvider.AndroidViewModelFactory(BaseApplication.getInstance())
    43. )[viewModelClass]
    44. }

    注释应该很清晰了,我们在ViewModelFragment中,创建了一个抽象函数,子类重写后获取DataBinding,至于ViewModel的构造和绑定,我们在此类中已经写好,子类直接调用就能绑定ViewModel。再创建一个BaseFragment继承ViewModelFragment,在BaseFragment中就做两件事:1.调用initViewModel将ViewModel和自己绑定;2.重写initBinding获取dataBinding

    1. /**
    2. * 继承自ViewModelFragment
    3. * 做两件事情:1、重写initBinding;2、调用initViewModel
    4. */
    5. abstract class BaseFragment<V : ViewBinding, VM : BaseViewModel>>(@LayoutRes private val layoutId: Int) :
    6. ViewModelFragment() {
    7. protected val TAG = BaseFragment::class.java.simpleName
    8. protected val mHandler: Handler = object : Handler(Looper.getMainLooper()) {
    9. override fun handleMessage(msg: Message) {
    10. }
    11. }
    12. /**
    13. * 抽象工厂类定义的业务方法
    14. * 本类相当于工厂类,要实现这些方法
    15. * 根据xml的id layoutId构建ViewBinding
    16. */
    17. override fun initBinding(inflater: LayoutInflater, container: ViewGroup?): V =
    18. DataBindingUtil.inflate(inflater, layoutId, container, false)
    19. /**
    20. * 这里是将xml的id layoutId绑定给对应的fragment,也就是fragment展示的页面
    21. */
    22. override fun onCreateView(
    23. inflater: LayoutInflater,
    24. container: ViewGroup?,
    25. savedInstanceState: Bundle?
    26. ): View? {
    27. mViewBinding = initBinding(inflater, container) //调用构建viewBinding获取到viewBinding
    28. mViewModel = initViewModel(this) //获得viewModel,这里的viewModel是绑定了当前fragment的生命周期的
    29. lifecycle.addObserver(mViewModel) //观察者模式,lifecycle就是被观察者,持有一个观察者集合List,当状态发生改变,通知这个集合里的ViewModel,同时viewModel中必须持有这个lifecycle对象
    30. return mViewBinding.root //显示页面
    31. }
    32. override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    33. super.onViewCreated(view, savedInstanceState)
    34. initView()
    35. }
    36. protected open fun initView(){}
    37. }

    其实我的理解就是创建基类将DataBinding和ViewModel的绑定都放在基类中,这样我们创建好基类后,在后续开发中,就按照这个标准去写,省去很多事,接下来就是讲一讲生命周期

  • 相关阅读:
    docker基本管理
    DataBinding 进阶用法
    七月集训(20)BST
    1440. 计算布尔表达式的值(常看看)
    Vue3使用ElementUI按需自动引入
    城商行两地三中心存储架构设计实践分享
    发送短信v2
    JSR303校验(1)
    04-HTTPS证书格式及转换
    四十二、《大数据项目实战之用户行为分析》多框架整合实时分析用户行为日志数据流
  • 原文地址:https://blog.csdn.net/somethingstill/article/details/107159380