java mvvm_MVVM

mvvm与mvp类似也分为三层

Model 层,主要负责数据的提供。

Model 层提供业务逻辑的数据结构(比如,实体类),提供数据的获取(比如,从本地数据库或者远程网络获取数据),提供数据的存储。

View 层,主要负责界面的显示。

View 层不涉及任何的业务逻辑处理,它持有 ViewModel 层的引用,当需要进行业务逻辑处理时通知 ViewModel 层。

ViewModel 层,主要负责业务逻辑的处理。

ViewModel 层不涉及任何的视图操作。通过官方提供 Data Binding 库,View 层和ViewModel 层中的数据可以实现绑定,ViewModel 层中数据的变化可以自动通知 View 层进行更新,因此 ViewModel 层不需要持有 View 层的引用。ViewModel 层可以看作是 View 层的数据模型和 Presenter 层的结合。

具体实现

由于功能过于单一所以这里讲全部类放在同一个文件下,平时的项目中可以根据模块进行划分 然后在模块下进行 model,view,viewModel 的划分。

e09a1dabc9d5

Talk is cheap. Show  the code for you

1. 添加Glide、Retrofit、RxJava的依赖

implementation 'com.squareup.retrofit2:retrofit:2.4.0'                                    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'                    implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'                    implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'                                  implementation 'io.reactivex.rxjava2:rxjava:2.1.12'                                      implementation 'com.github.bumptech.glide:glide:4.6.1'                      annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'

2. 添加网络访问权限                                                                                                               

3. 启用DataBindingdataBinding{                                                                                                      enabled=true                                                                                               }

4. 创建实体类ImageBeanclass ImageBean {

var tooltips:TooltipsBean? =null

var images:List? =null

class TooltipsBean {

var loading:String? =null

var previous:String? =null

var next:String? =null

var walle:String? =null

var walls:String? =null

}

class ImagesBean {

val BASE_URL ="https://www.bing.com/"

var startdate:String? =null

var fullstartdate:String? =null

var enddate:String? =null

var url:String? =null

var urlbase:String? =null

var copyright:String? =null

var copyrightlink:String? =null

var quiz:String? =null

var isWp:Boolean =false

var hsh:String? =null

var drk:Int =0

var top:Int =0

var bot:Int =0

var hs:List? =null

}

}

由于接口并没有返回图片url前缀信息,所以我在ImagesBean的内部手动添加了一个变量BASE_URL来存储图片url前缀信息。

由于采用MVVM架构,View层与ViewModel层的通信是通过LiveData这个架构组件实现的,不同于MVP架构中通过接口来通信,所以还要对数据加载的状态和错误信息进行维护。这里创建一个包装类来维护数据的状态和错误信息,以便View层可以对数据加载错误信息进行响应和处理。

5.创建Data包装类class Data(var data: T?, var errorMsg: String?)

6. 创建数据访问接口ImageRepertoryclass ImageRepertory {

private val mRetrofit:Retrofit =Retrofit.Builder()

.baseUrl("https://cn.bing.com/")

.addConverterFactory(GsonConverterFactory.create())

.addCallAdapterFactory(RxJava2CallAdapterFactory.create())

.build()

fun getImage(format:String,idx:Int,n:Int):Observable {

return mRetrofit.create(ApiService::class.java).getImage(format,idx,n)

}

}

7.创建APIServiceinterface ApiService {                                                           @GET("HPImageArchive.aspx")                                                                                 abstract fun getImage(@Query("format")format:String,@Query("idx")idx:Int,@Query("n")n:Int):Observable}

项目采用了Retrofit+Rxjava作为网络访问框架。首先ImageRepertory内部有一个Retrofit实例,并且在构造函数中进行Retrofit的配置和创建。接着创建一个Service接口,其中的getImage方法用来获取图片信息,方法返回一个ImageBean的Observable对象。

8. 编写ImageViewModelclass ImageViewModel :ViewModel() {

val image:MutableLiveData>

private val mRepertory:ImageRepertory

private var idx:Int =0

init {

image =MutableLiveData>()

mRepertory =ImageRepertory()

idx =0

}

fun LoadImage() {//加载图片的请求}

fun nextImage() { //加载下一张图片的请求}

fun previousImage() {//加载上一张图片的请求}

}

1.首先这个类要继承自 ViewModel 这个类,以便在创建时与View层的生命周期相关联。

2.然后是三个成员变量:mImage这个变量的类型是MutableLiveData用来存放图片信息,以便当信息发生变化时及时通知View层来更新界面; mRepertory这个变量来负责数据访问; idx这个变量来记录当前的图片页码。这三个变量在构造函数中创建并初始化

3.接着为mImage添加了getter方法以便View层可以对其进行观察与响应。

4.loadImage,nextImage和previousImage这三个方法分别对应图片的加载,下一张和上一张,并且内部通过访问mRepertory的方法来完成数据的访问,又对返回的数据进行判断处理并触发mImage的setValue方法来对数据进行更新由于代码较长 如果有需要请查看源码

9.界面编写

e09a1dabc9d5

界面较为简单,就一个 ImageView 控件,外加三个按钮这里就不过多的阐述了,由于涉及到图片的加载所以自定义了一个图片加载的属性

10.自定义属性BindingAdapter

使用@android.databinding.BindingAdapter注解来让编译器知道你的属性名。在方法中来对属性值进行处理,这里使用了Glide来进行网络图片的加载public class BindingAdapter {

@android.databinding.BindingAdapter("url")

public static void setImageUrl(ImageView imageView,String url) {

Glide.with(imageView.getContext())

.load(url)

.into(imageView);

}

}

11. 编写ImageActivity

1.三个成员变量:mBinding数据绑定对象,用来实现数据绑定;mViewModel用来获取数据,实现与数据层的解耦;mProgressDialog用来弹出加载提示框。这三个变量在 init 方法中初始化,mBinding用DataBindingUtil的setContentView方法实现视图层的绑定;mViewModel要使用ViewModelProvider的get方法完成创建。接着对ViewModel中的LiveData进行观察,在observe方法中处理错误和数据的绑定。内部类Presenter用来对点击事件进行响应,并且也要在oncreate方法里与mBinding进行绑定,详情请看源码。

e09a1dabc9d5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值