MVVM的构建(java&kotlin)

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

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

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

MVVM的构建(java&kotlin)_第1张图片

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

MVVM的构建(java&kotlin)_第2张图片

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

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

MVVM的构建(java&kotlin)_第3张图片

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

MVVM的构建(java&kotlin)_第4张图片

 

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

     MVVM的构建(java&kotlin)_第5张图片

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

MVVM的构建(java&kotlin)_第6张图片

 

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

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

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

1.创建ViewModel基类

MVVM的构建(java&kotlin)_第7张图片

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

/**
 * 带databinding和BaseViewModel的fragment
 * dataBinding就是各个fragment自己布局的binding
 * VM就是给每个fragment创建的ViewModel
 * 其实这个类,就是相当于抽象工厂模式,封装了构造ViewModel的方法
 */
abstract class ViewModelFragment> : Fragment() {

    private val TAG = javaClass.simpleName
    protected lateinit var mViewBinding: V
    protected lateinit var mViewModel: VM

    //定义一个获取dataBinding的抽象函数,子类可重写此函数,构造dataBinding
    abstract fun initBinding(inflater: LayoutInflater, container: ViewGroup?): V

    /**
     * 每个视图,都要持有一个ViewModel
     * 这里是给每个视图绑定viewModel
     * 将子类的ViewModel传进来绑定ViewModel
     */
    @Suppress("UNCHECKED_CAST")
    fun initViewModel(viewModelStoreOwner: ViewModelStoreOwner): VM {
        var modelClass: Class?;
        val type: Type? = javaClass.genericSuperclass
        modelClass = if (type is ParameterizedType) {
            type.actualTypeArguments[1] as Class
        } else {
            null
        }

        if (modelClass == null) {
            modelClass = BaseModel::class.java as Class
        }
        //最终目的就是创建ViewModel,绑定了ViewModel的生命周期,也就是在这里,viewModel持有了lifecycle的对象
        return ViewModelProvider(
            viewModelStoreOwner,
            ViewModelProvider.AndroidViewModelFactory(BaseApplication.getInstance())
        )[modelClass]
    }

    /**
     * 绑定ViewModel
     */
    fun  obtainViewModel(viewModelClass : Class)=
        ViewModelProvider(
            viewModelStore,
            ViewModelProvider.AndroidViewModelFactory(BaseApplication.getInstance())
        )[viewModelClass]

}

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

/**
 * 继承自ViewModelFragment
 * 做两件事情:1、重写initBinding;2、调用initViewModel
 */
abstract class BaseFragment>(@LayoutRes private val layoutId: Int) :
    ViewModelFragment() {

    protected val TAG = BaseFragment::class.java.simpleName

    protected val mHandler: Handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {

        }
    }

    /**
     * 抽象工厂类定义的业务方法
     * 本类相当于工厂类,要实现这些方法
     * 根据xml的id layoutId构建ViewBinding
     */
    override fun initBinding(inflater: LayoutInflater, container: ViewGroup?): V =
        DataBindingUtil.inflate(inflater, layoutId, container, false)

    /**
     * 这里是将xml的id layoutId绑定给对应的fragment,也就是fragment展示的页面
     */
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        mViewBinding = initBinding(inflater, container)  //调用构建viewBinding获取到viewBinding
        mViewModel = initViewModel(this)    //获得viewModel,这里的viewModel是绑定了当前fragment的生命周期的
        lifecycle.addObserver(mViewModel)       //观察者模式,lifecycle就是被观察者,持有一个观察者集合List,当状态发生改变,通知这个集合里的ViewModel,同时viewModel中必须持有这个lifecycle对象

        return mViewBinding.root  //显示页面
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        initView()
    }

    protected open fun initView(){}
}

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

你可能感兴趣的:(学习记录,android)