欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MVVM+ViewBinding+Kotlin入门

程序员文章站 2022-06-07 18:53:21
...

本篇博客不作原理性分析,仅对还没有接触过MVVM,viewbinding,甚至说是kotlin的同学一个入门练习项目,通过此篇博客,可以对MVVM架构,以及最近比较火的ViewBinding有一个初步认识。

先说Kotlin,Kotlin1.0还没正式发布的时候就已经开始研究了,但到现在也没有真正的去用kotlin写过项目,原因很简单,公司平时做项目基本都用的java,而且当时很多第三方库也都是用的java,并且kotlin的出世总有一种感觉是谷歌为了摆脱甲骨文而不得已才出的语言,所以当时大家也都没把它当回事,毕竟还是java大法好,上天入地无所不能。在研究了其语法后,给我的印象就是语法简洁,甚至于熟练java编程的我一时感觉无所适从(心中骂道这gr的语法),直到现在我依然有点排斥Kotlin,原因就是,

为什么我要去用Kotlin

而转Kotlin开发的同学,原因也无外乎这几个:
1.谷歌大厂出的,且定为了安卓官方一级开发语言,必须要用;
2.很多开发者都在用了,我不用就out了;
3.公司要求用kotlin,所以我不得不用;
4.kotlin语法简洁,有很多java没有的新特性,开发效率高;
5…

这些理由其实都不能打动我,以至于放弃java转投kotlin,因为作为一个将近10年的java开发者来说,所谓的开发效率问题是不存在的,即便我写5行代码,你只用写1行代码,在开发效率上我也绝不会比你低,除非老板指定要用kotlin,否则就开除你,那就没办法了。可能大家觉得我因循守旧,排斥创新,但我是真的没有用kotlin的欲望,因为它仅仅是换了一个编程语言而已,对开发出来的app在编译与运行效率上没有任何改变,我还要花大量学习成本,以及可能在开发过程中遇到未知风险,我为什么要用你呢?相信有不少同学和我有同样的心态。

但为什么今天又用Kotlin了呢? 其实,做程序开发是一个不断学习的过程,一天不去接触学习新东西,你就会落后甚至过时,所以说当出现新玩意的时候,你可以不用,但不能不会,只有这样,你才能在职业生涯中游刃有余,就像今天说的这个MVVM框架,以及ViewBinding,我相信很多开发者刚把mvp模式玩6,RxJava,Retrofit弄懂,甚至于有些还在用mvc模式,你就告诉我他们统统过时了???我尼玛,这要累死人的节奏???没办法,程序界发展就是这么快,稍不留神你就已经落伍了,这也是为什么程序员吃青春饭这一说法的由来了,你跟不上节奏,甚至于连去跟节奏的心也没有了,那就只能被淘汰了!

闲话说了这么多,进入正题吧!如果你问我,目前最流行的移动端开发模式是什么,我会毫不犹豫的告诉你:MVP+Rxjava+Retrofit+EventBus…,MVP优点自不必说,但缺点相信现在还在用MVP模式的你会深有体会,可以说成也P,败也P,随着项目的扩大,界面的增多,接口的增多,P会越来越多,P中的回调也会越来愈多,在某个界面想重用某个接口时,如果不想进入回调地狱,就只能再写一个新的P,相当麻烦。还有一个缺点就是,在使用p的时候,总是要实现回调接口,再声明p,然后attach,界面销毁时再调用detach,否则就可能会内存泄漏,这两点是不是不能忍?所以MVVM就出现了,对于MVVM,你可以这么理解,M+V+VM就是把MVP的Presenter换成ViewModel,VM不但可以替代Presenter的功能,还能解决Presenter的两个缺点,上面说过,本篇不作原理性分析,因为这类文章太多了,再分析分析也是多次一举,所以就直接上代码:

ViewModel的简单用法:
在mvp模式下,当我们有服务器交互也就是需要调用接口时,我们便会为此界面创建一个Presenter,同样的,mvvm模式下,我们要为这个界面创建一个ViewModel,例如我们为MainActivity创建MainViewModel :

class MainViewModel : ViewModel() {


}

需要继承ViewModel,并且ViewModel中一般会配合LiveData使用:

class MainViewModel : ViewModel() {
    var data = MutableLiveData<String>()
    fun getData() {
        //模拟数据请求
        var result = "请求结果"
        data.value = result
    }
}

在MainActivity中声明,并使用MainViewModel :

 mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
 mainViewModel.getData()//调用方法,模拟请求数据
  mainViewModel.data.observe(this, Observer {//观察data变化,相当于接口请求回调函数
      textView.text=it
  })

LiveData的observe,就是一个观察者,发现数据有变化时就会立马通知你,参数it就是MainViewModel 中 MutableLiveData(),<>中声明的数据类型的数据,我们不要像presenter一样 需要attach和detach,也不需要些回调接口,只用观察,就这么简单!

再来看ViewBinding:
MVVM+ViewBinding+Kotlin入门
文档连接:https://developer.android.google.cn/topic/libraries/view-binding

ViewBinding和DataBinding的区别:
ViewBinding和DataBinding均会生成可用于直接引用视图的绑定类。不过,这两者之间存在明显差异:
1.DataBinding仅处理使用 代码创建的数据绑定布局。
2.ViewBinding不支持布局变量或布局表达式,因此它不能用于在 XML 中将布局与数据绑定。

ViewBinding仅是节省了findview的步骤,并且启用后,每当创建一个xml布局文件,便会自动生成一个对应的ViewBinding类,仅需在界面里的setContentView传入ViewBinding.根视图root即可使用,使用方法为ViewBinding对象.id

 private lateinit var binding: ActivityMainBinding
  binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
 binding.mRecyclerView.layoutManager = LinearLayoutManager(this)
        binding.mRecyclerView.adapter = articleAdapter

使用起来也是相当简单,另外项目中封装了相对简单网络请求,

class HttpUtil {

    /**
     * 通用网络请求方法
     */
    inline fun <reified T> getData(api: String, onResultListener: OnResultListener) {
        GlobalScope.launch(Dispatchers.Main) {
            withContext(Dispatchers.IO) {
                val data = URL(Const.BASE_URL + api).readText()
                val result = Gson().fromJson(data, T::class.java)
                withContext(Dispatchers.Main) {
                    onResultListener.onResult(result)
                }
            }
        }
    }

    /**
     * 单例模式
     */
    companion object {
        @Volatile
        private var httpUtil: HttpUtil? = null

        fun getInstance() = httpUtil ?: synchronized(this) {
            httpUtil ?: HttpUtil().also { httpUtil = it }
        }
    }

    /**
     * 网络请求回调
     */
    interface OnResultListener {
        fun onResult(obj: Any?)
    }
}

因为是入门项目,所以没有任何技术难点,一看就懂,适合准备入门的开发者!

MVVM+ViewBinding+Kotlin入门

项目下载链接:https://download.csdn.net/download/baiyuliang2013/12358988