概念性的描述就不写了,直接上代码
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的绑定
/*** 带databinding和BaseViewModel的fragment* dataBinding就是各个fragment自己布局的binding* VM就是给每个fragment创建的ViewModel* 其实这个类,就是相当于抽象工厂模式,封装了构造ViewModel的方法*/
abstract class ViewModelFragment> : Fragment() {private val TAG = javaClass.simpleNameprotected lateinit var mViewBinding: Vprotected lateinit var mViewModel: VM//定义一个获取dataBinding的抽象函数,子类可重写此函数,构造dataBindingabstract 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.genericSuperclassmodelClass = 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.simpleNameprotected 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获取到viewBindingmViewModel = 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的绑定都放在基类中,这样我们创建好基类后,在后续开发中,就按照这个标准去写,省去很多事,接下来就是讲一讲生命周期