目录:
- MVVM的3大基本结构介绍
1.1).View层
1.2).Model层
1. 3).ViewModel
2. MVVM的实战案例
- mvvm如何解偶的?
mvvm如何实现双向绑定的?
4. MVVM对比MVP优缺点比较
4.2 MVVM的优缺点:
5. MVVM问题思考
1. MVVM的3大基本结构介绍
MVVM是Model-View-ViewModel的简写。
了解MVVM+data binding的开发模式。所以学习之前一定要先学习Data Binding!
![](https://img.haomeiwen.com/i11218161/8f4cb82c3f94f619.jpg)
至于MVVM基本上和MVP一模一样,感觉只是名字替换了一下。
MVVM架构的关键概念是数据绑定(Data Binding)。
通过数据绑定,ViewModel可以将数据直接绑定到View上,使得View能够自动更新,并且保持与ViewModel的同步。
MVVM在MVP的基础上加入了双向绑定,使View能够感知ViewModel中的数据变化,ViewModel能够感知View数据的变化
MVVM结构二
MVVM:里面的ViewModel不是jetpack里面的ViewModel
Model:处理数据的,比如网络请求
![](https://img.haomeiwen.com/i11218161/939f619e45b448f4.jpg)
总结分析:
1).View层: 是展示数据的,以及接收到用户的操作传递给viewModel层,通过dataBinding实现数据与view的单向绑定或双向绑定
2).Model层: 最重要的作用就是获取数据了,当然不止于此,model层将结果通过接口的形式传递给viewModel层,和MVP的Mode是一样的。
3).ViewModel 层通过调用model层获取数据,以及业务逻辑的处理。viewModel 和MVP中的presenter 的作用类似 ,只不过是通过 databinding 将数据与ui进行了绑定。
个人理解VM在取到Model层的数据后,应该是通过LiveData的post或者set方法来通知View层有数据更新, 一个vm对于一个view,
viewMode l里面封装livedata, 如果有多个bean那么livedada岂不是有多个, 是的
4). VM和View层是要解耦的。怎么解耦的? 通过Databing.
MVVM的架构表格:
![](https://img.haomeiwen.com/i11218161/2c89d0cfcd2ddd1e.jpg)
2. MVVM的实战案例
问题: MVVM+ViewModel+LiveData+DataBind如何使用?
大型项目实战:
1) View层: 传入<ViewModel,Databing >,把databing绑定viewmode,然后通过ViewModel去请求数据,然后再拿到ViewModel的引用,进行数据观察,observe
class UpLoadFragment(layoutId: Int) :
TransferBaseFragment<UploadViewModel, FragmentUploadBinding>(layoutId) {
private lateinit var mAdapter: UploadAdapter
override fun loadDate() {
mViewModel.dataList.observe(this) {
setNoFileLayoutVisible(it.isNullOrEmpty())
mAdapter.updateData(it)
}
println("getTemporarySk:getData")
mViewModel.getData()
}
fun initRecyclerView() {
mAdapter = context?.let {
UploadAdapter(it)
}!!
binding.transferRecyclerView.adapter = mAdapter
}
}
2).ViewModel:里面数据用muableLiveData,得到Model的数据,然后PostView,发送出去,然后VIew那边就可以通过观察者接收
class UploadViewModel : AppBaseViewModel() {
var dataList = MutableLiveData<MutableList<UploadTask>>()
fun getData() {
dataList.postValue(adapterData())
}
/***
* 从上传器中获取任务
*/
open fun adapterData(): MutableList<UploadTask> {
val itemList = mutableListOf<UploadTask>()
BNLog.d("UploadAndDownViewModel", "" + uploadingTask.size)
return itemList
}
}
基类:实现了LifecycleObserver接口
open class AppBaseViewModel(
val app: Application = CloudServiceApp.getInstance()
) : AndroidViewModel(app), LifecycleObserver {
3).model:网络请求,没有独立开,都放在了ViewMode层,可以进行优化!
案例二:
1). 定义Model
data class Weather(val city: String, val temperature: String)
class WeatherRepository {
fun getWeather(city: String): Weather {
// 从网络或其他数据源获取天气数据
return Weather(city, "25°C")
}
}
2). 定义View:
class WeatherActivity : AppCompatActivity() {
private lateinit var viewModel: WeatherViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_weather)
viewModel = ViewModelProvider(this).get(WeatherViewModel::class.java)
viewModel.weather.observe(this, { weather ->
updateUI(weather)
})
val cityButton = findViewById<Button>(R.id.cityButton)
cityButton.setOnClickListener {
// 用户点击城市按钮时触发切换城市的操作
val selectedCity = // 通过弹出对话框或其他方式获取用户选择的城市
viewModel.fetchWeather(selectedCity)
}
}
3). 定义ViewModel:
class WeatherViewModel : ViewModel() {
private val weatherRepository = WeatherRepository()
private val _weather = MutableLiveData<Weather>()
val weather: LiveData<Weather> = _weather
fun fetchWeather(city: String) {
val weatherData = weatherRepository.getWeather(city)
_weather.value = weatherData
}
}
以上示例中,我们通过定义Model、View和ViewModel三个部分来实现MVVM架构。
ViewModel负责从Model层获取天气数据,并通过LiveData观察的观察者, 将数据更新到View层。
View层通过观察LiveData的变化来更新UI,并通过ViewModel执行相应的业务逻辑。
问题: 如何更新UI的?
1). ViewModel----------------->LiveData---------------->View
![](https://img.haomeiwen.com/i11218161/cfabb7419f3806e7.jpg)
ViewModel负责从Model层获取天气数据,并通过LiveData观察的观察者, 将数据更新到View层。
问题: view变化是如何通知到Model层的?
2). View-------------------->ViewModel------------------->Model(View变化了input值, 导致ViewModel数据(model)变化了)
![](https://img.haomeiwen.com/i11218161/77d19040758f6cf7.jpg)
使用
1). 使用databanding, view里面包含了viewModel (绑定View层的组件到ViewModel层的数据)
2). viewModel里面封装了liveData
3). 使用的时候 , 数据变化, 通过LiveData将数据更新到View层
View层有输入的变化, 会到经过ViewModel, android:text="@{viewModel.userOutput), ViewModel会执行对应的业务逻辑!
画一个完整的图! :
![](https://img.haomeiwen.com/i11218161/26c5242640f01327.jpg)
3. MVVM 如何实现双向绑定的?
有人说MVVM核心是双向绑定,没有使用Databinding的项目都是假的MVVM。 也就是:MVVM == 双向绑定,双向绑定 == Databinding, MVVM == Databinding。
通过Android提供的数据双向绑定库data binding 将Acitvity/xml视图层与ViewModel绑定。在xml布局文件中,通过@{}
来表示单向绑定或者@={}
来表示双向绑定
3.1) 什么是双向绑定:
双向数据绑定则是MVVM模式中的一个重要特性,它允许数据在Model和View之间自动同步,减少了手动设置和监听数据变化的代码量。
重点通过中间: ViewMode
ViewModel的第2层意思: 数据共享!
Model与View之间通过ViewMode关联,ViewModel负责将Model数据的变化显示到View上,通过将View的改变反馈到Model上这就是我们常说的双向绑定数据机制。
3.2 ) 问题: 双向绑定具体是怎么实现的?
则允许数据的双向同步更新,即当Model中的数据改变时,View自动更新;当用户在View中修改数据时,Model也会相应更新。通过解耦数据和界面逻辑,
4. MVVM架构与MVP架构的对比
1).经过数据双向绑定之后,我们不在需要想MVP中写那么多接口回调方法区实现视图层和业务层的交互。业务层也不再持有视图层的引用。
数据绑定:MVVM通过数据绑定实现了View和ViewModel的自动同步,而MVP需要通过Presenter手动更新View。
-
.代码量: (简洁 )MVP架构通常需要编写更多的代码,因为Presenter需要显式地处理UI更新。MVVM通过数据绑定减少了冗余的UI更新代码。 3) .可测试性:由于ViewModel与View之间的解耦,MVVM架构更易于编写单元测试。而在MVP架构中,Presenter需要模拟View的行为,测试相对复杂。
-
.学习曲线:MVVM引入了数据绑定等新概念,相对而言学习曲线较陡。而MVP相对较简单,更容易理解和上手。
数据驱动UI
在使用MVC或MVP开发时,我们如果要更新UI,首先需要找到这个view的引用,然后赋予值,才能进行更新。
在MVVM中,这就不需要了。MVVM是通过数据驱动UI的,这些都是自动完成
4.2 MVVM的优缺点:
优点总结:
1).经过数据双向绑定之后,我们不在需要想MVP中写那么多接口回调方法区实现视图层和业务层的交互。业务层也不再持有视图层的引用。
2). View有ViewModel的引用,但是ViewModel没有任何关于View的信息。
3).View和Model的双向绑定是支持生命周期检测的,不会担心页面销毁了还有回调发生,这个由lifeCycle完成。
缺点:
1).MVVM:编译时,但是对内存要求有点高
- .数据绑定方式使得bug难以确定是在View中还是在Model中。
通过这种方式进行数据双向绑定后,xml中会多出一些标签、表达式、甚至和业务有点的简单计算代码。这不利于业务的逻辑的查看。并且由于双向绑定是data binding实现的。在这个过程中, 如果出现bug导致数据没有被感知改变,不方便排错,因为xml不能debug调试。
- .ViewModel持有Model的依赖。.view和viewmodel都绑定了一起??????
5. MVVM问题思考
MVVM不用databing也叫MVVM??????????
5.1 问题MVVM:如果不用databing可以吗?
宝能封装的就是,通过livedatabus实现的。
当然可以,这样view和ViewModel就没有绑定关系,可以用kotlin里面的bind。
5.2. 问题viewModel的更新怎么会改变model?
我们使用Google提供的DataBinding技术来完成数据绑定,以实现View和ViewModel层的交互。
网友评论