码迷,mamicode.com
首页 > 移动开发 > 详细

一篇文章彻底弄懂Android-MVVM

时间:2021-02-27 13:28:18      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:实现   服务器   undle   可读性   ble   数据呈现   mutable   ext   软件   

转:

一篇文章彻底弄懂Android-MVVM

在学习一个技术之前,我们首先要搞清为什么要用它、用它以后会有什么好处,这样我们才能有兴趣的学习下去。

一、为什么要用MVVM?

我为什么要用这个什么MVVM,我就平常写和它有什么不同吗?

首先我们要说一下,使用MVVM后,程序会有哪些变化:

1.MVVM并不会提升程序的性能,甚至如果用不好还会降低性能。

2.MVVM会增大代码的总量。

3.阅读MVVM的代码你必须不停的跳来跳去,跳到你恶心想吐。

啥?你在搞笑吗?那我为什么还要用它?且慢,我还没说最重要的一条。

4.MVVM将让你的程序完全解耦。当然,是正确使用的前提下。

为了最后这一条,我们用前3条的牺牲完全不过分,真正写代码的时候,我们面对的往往不是性能的些许提升,也不是几十或几百K的包大小增大带来的问题,而是程序不停迭代所带来的程序稳定性要求。而这也是MVVM大显身手的地方,MVVM能够完全让你的业务功能组件化,让我们需要什么就调什么,并且组件可以在不同页面之间复用;在写业务组件的时候,我们可以完全集中精力,只管写组件要完成的功能,而无需分神它顾。

读到这,相信你应该对MVVM稍微有点兴趣了吧。

二、MVVM到底是什么?

MVVM,是Model、View、ViewModel三者的缩写,它是一种程序的设计框架,是一种设计思路。不同的人实现MVVM,所用的构成技术、实现以后的性能都是不一样的。千万不要觉得它有多深奥,他其实就是由一系列代码(或技术)构成的一个程序的底座。我们在良好底座上开发出来的程序稳定性更高,可扩展性更强。

下面我们挨个来来说Model、View、ViewModel。

1.Model:数据提供。

Model在程序中专门用于提供数据,不管是网络请求获得的数据,还是数据库获得的数据,统统写在Model里。Model层独立性相当强,它只用来提供数据,而不管数据是用来做什么的。

2.View:视图元素和视图元素初始化。

View在Android中指代的就是我们常见的布局文件和Activity中的元素初始化部分。总之,所有一切我们在Android上肉眼能看见的东西都是View。在View层里,我只对UI做初始化,比如将TextView设置字体大小,为Banner控件设置滚动速度等等,这些大多可以直接在布局文件中完成。

3.ViewModel:操作业务数据,并将数据呈现在View上。

ViewModel根据业务需要,从Model层调取相关数据,然后更新View层相关元素。

说起来有点抽象,别急,下面我们用一个简单的例子来解释它们怎样互相配合,你很快就会明白。

在例子中,我们使用Google提供的DataBinding技术来完成数据绑定,以实现View和ViewModel层的交互。

【??时间】

技术图片

例子非常非常简单,一个仓库管理的页面,一共三个元素,其中更新时间和仓库物品列表是从服务器动态获取的。

平常写的话,我们会在Activity内完成所有的操作,先进行网络请求,得到数据后为TextView设置文字、为RecycleView设置Adapter。但使用了MVVM后,代码将被拆分为三个部分,我们按View、ViewModel、Model的顺序直接上代码,随后在一一解释:


View层:





    

        

    

    

        

        

        

    



ViewModel层:

class StockManagementViewModel(mvvmViewModel: MVVMViewModel?) : BaseViewModel(mvvmViewModel) {

    fun load() {

        val newData = getModel(StockModel::class.java).getStockList()

        val time = getModel(StockModel::class.java).getUpdateTime()

        bindingData.data.clear()

        bindingData.data.addAll(newData)

        bindingData.updateTime = "更新时间:${time}"

        bindingData.notifyChange()

    }

    override fun onResumed() {

        super.onResumed()

        load()

    }

    val bindingData: BindingData = BindingData(mutableListOf(), "")

    data class BindingData(

            @Bindable val data: MutableList,

            @Bindable var updateTime: String

    ) : BaseObservable()

}

@BindingAdapter("android:stockGoodsViewLoader")

fun stockGoodsViewLoader(recyclerView: RecyclerView, data: List) {

    recyclerView.apply {

        layoutManager = LinearLayoutManager(recyclerView.context).apply {

            orientation = LinearLayoutManager.VERTICAL

        }

        adapter = StockManagementAdapter(recyclerView.context, data)

    }

}

Model层:

class StockModel(mvvmModel: MVVMModel?) : HttpModel(mvvmModel) {

    fun getStockList(): List {

        return mutableListOf().apply {

            add(StockGood("1", "钳子", 3))

            add(StockGood("2", "扳手", 12))

        }

    }

    fun getUpdateTime(): String {

        return Utils.DateUtil.getCurrentlyTimeByFormatter(Constant.DateFormat4)

    }

}

View层在我们这个例子中只有一个布局文件,布局文件是DataBinding的标准写法,在标签中写好控件需要的ViewModel。



        

    

然后将TextView和RecyclerView与ViewModel中的元素绑定好。

android:text="@{stockViewModel.bindingData.component2()}"
android:stockGoodsViewLoader="@{stockViewModel.bindingData.component1()}"

View没看明白没关系,先来看ViewModel。

还记得ViewModel的作用吗,我来重复一遍:它从Model层获取数据,然后更新视图。

这里ViewModel实现了Activity的生命周期函数,onResumed是ViewModel开始执行的地方

调用Model获取数据:

        val newData = getModel(StockModel::class.java).getStockList()

        val time = getModel(StockModel::class.java).getUpdateTime() 

更新视图

        bindingData.data.clear()

        bindingData.data.addAll(newData)

        bindingData.updateTime = "更新时间:${time}"

        bindingData.notifyChange()

这里注意, notifyChange方法是BaseObservable中的方法,用于通知视图刷新

因为我们已经在View层将数据绑定到了data和updateTime两个变量上,因此,我们只需要更新这两个变量,就可以完成View层视图的刷新,这也正是MVVM强大的地方。从这里就可以看出,View层和ViewModel层是高度解耦的,只通过两个变量相互关联,这样,ViewModel就有了非常高的独立性,可以轻而易举的被其他View调用,也可以从例子中的View层瞬间剔除,就像插上或拔出一个U盘那样简单。

Model层比较容易理解,由于只是一个例子,我们在这里并没有请求网络,实际开发过程中,你只需要使用你想使用的网络工具请求网络或调用数据库,获取到数据后返回给ViewModel层即可。

这里值得一题的是Activity中的代码:


class StockManagementActivity : MVVMActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentViewByDataBinding(R.layout.actibity_stock_management)

        dataBinding.stockViewModel = getViewModel(StockManagementViewModel::class.java)

    }

}

可以看到,Activity中几乎没有逻辑代码,仅仅有一行来实例化ViewModel。MVVM就这样,将业务逻辑完整从Activity中拆分为独立的三块,不仅解放了Activity,更使整个代码的逻辑清晰,可读性极强,并且功能块之间互不干扰,这也就实现了我们开头所说的组件化开发。

三、总结

怎么样,MVVM还不错吧?如果您曾经了解过MVC、MVP,相信本文一定很容易理解,MVVM只不过的它们的“升级版”,实现过程不同,目标却是相同的。这些设计思想并不是十分深奥的东西,本质就是让软件质量变得更好,如果不明白它们的原理,不仅不会让代码质量提高,反而会使程序变得不知所云,得不偿失。

另外说一下,本文主讲MVVM,DataBinding的用法和原理没有过多涉及,但相信看过本文以后,您应该对它也有了一定的了解了吧。我开头说过,MVVM实现的技术各不相同。DataBinding是Goodle出品,并且Android Studio中支持的相当不错,因此被我采用。在了解了MVVM的机制以后,你完全可以选择你想使用的技术,构建你自己的MVVM框架。如果各位有兴趣,我可以写一个关于DataBinding的文章。当然网络上关于DataBinding的也很多,大家也可以作为参考。

小生才疏学浅,文中必有遗漏和错误,十分欢迎阅读过的同学指正,大家一起讨论!

转:

一篇文章彻底弄懂Android-MVVM

一篇文章彻底弄懂Android-MVVM

标签:实现   服务器   undle   可读性   ble   数据呈现   mutable   ext   软件   

原文地址:https://www.cnblogs.com/wangtcc/p/14454739.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!