专栏名称: 安卓开发精选
伯乐在线旗下账号,分享安卓应用相关内容,包括:安卓应用开发、设计和动态等。
目录
相关文章推荐
鸿洋  ·  全新导航库 Jetpack ... ·  19 小时前  
复利大王  ·  国产美女宁宁 ·  20 小时前  
复利大王  ·  三名日本女技师来北京打工被抓 ·  20 小时前  
复利大王  ·  保时捷跌下神坛 ·  昨天  
51好读  ›  专栏  ›  安卓开发精选

如何构建 Android MVVM 应用程序

安卓开发精选  · 公众号  · android  · 2017-02-27 22:33

正文

请到「今天看啥」查看全文


new ObservableField ();

public final ObservableField html = new ObservableField ();

public final ObservableField title = new ObservableField ();

// 一个变量包含了所有关于View Style 相关的字段

public final ViewStyle viewStyle = new ViewStyle ();

//命令绑定(command)

public final ReplyCommand onRefreshCommand = new ReplyCommand (() -> {

})

public final ReplyCommand onLoadMoreCommand = new ReplyCommand (( p ) -> {

});

//Child ViewModel

public final ObservableList itemViewModel = new ObservableArrayList ();

/** * ViewStyle 关于控件的一些属性和业务数据无关的Style 可以做一个包裹,这样代码比较美观,

ViewModel 页面也不会有太多的字段。 **/

public static class ViewStyle {

public final ObservableBoolean isRefreshing = new ObservableBoolean ( true );

public final ObservableBoolean progressRefreshing = new ObservableBoolean ( true );

}


  • Context

Context 是干嘛用的呢,为什么每个ViewModel都最好需要持了一个Context的引用呢?ViewModel 不做和UI相关的事,不操作控件,也不更新UI,那为什么要有Context呢?原因主要有以下两点,当然也有其他用处,调用工具类、帮助类可能需要context参数等:


  • 通过图1中,我们发现ViewModel 通过传参给Model 然后得到一个Observable ,其实这就是网络请求部分,做网络请求我们必须把Retrofit Service返回的Observable 绑定到Context的生命周期上,防止在请求回来时Activity已经销毁等异常,其实这个Context的目的就是把网络请求绑定到当前页面的生命周期中。

  • 在图1中,我们可以看到两个ViewModel 之间的联系是通过Messenger来做,这个Messenger 是需要用到Context,这个我们后续会讲解。


  • Model

Model 是什么呢,其实就是数据原型,也就是我们用Json转过来的Java Bean,我们可能都知道,ViewModel要把数据映射到View中可能需要大量对Model的数据拷贝,拿Model 的字段去生成对应的ObservableField(我们不会直接拿Model的数据去做展示),这里其实是有必要在一个ViewModel 保留原始的Model引用,这对于我们是非常有用的,因为可能用户的某些操作和输入需要我们去改变数据源,可能我们需要把一个Bean 从列表页点击后传给详情页,可能我们需要把这个model 当做表单提交到服务器。这些都需要我们的ViewModel 持有相应的model。


  • Data Field (数据绑定)

Data Field 就是需要绑定到控件上的ObservableField字段, 无可厚非这是ViewModel的必须品。这个没有什么好说,但是这边有一个建议:

这些字段是可以稍微做一下分类和包裹的,比如说可能一些字段绑定到控件的一些Style属性上(如果说:长度,颜色,大小)这些根据业务逻辑的变化而动态去更改的,对于着一类针对View Style的的字段可以声明一个ViewStyle类包裹起来,这样整个代码逻辑会更清晰一些,不然ViewModel里面可能字段泛滥,不易管理和阅读性较差。而对于其他一些字段,比如说title,imageUrl,name这些属于数据源类型的字段,这些字段也叫数据字段,是和业务逻辑息息相关的,这些字段可以放在一块。


  • Command (命令绑定)

Command (命令绑定)说白了就是对事件的处理(下拉刷新,加载更多,点击,滑动等事件处理),我们之前处理事件是拿到UI控件的引用,然后设置Listener,这些Listener 其实就是Command,但是考虑到在一个ViewModel 写各种Listener 并不美观,可能实现一个Listener就需要实现多个方法,但是我们可能只想要其中一个有用的方法实现就好了。同时实现Listener 会拿到UI的引用,可能会去做一些和UI相关的事情,这和我们之前说的ViewModel 不持有控件的引用,ViewModel不更改UI 有相悖。更重要一点是实现一个Listener 可能需要写一些UI逻辑才能最终获取我们想要的,简单一点的比如说,你想要监听ListView滑到最底部然后触发加载更多的事件,这时候你就要在ViewModel里面写一个OnScrollListener,然后在里面的onScroll方法中做计算,计算什么时候ListView滑动底部了,其实ViewModel的工作并不想去处理这些事件,它专注做的应该是业务逻辑和数据处理,如果有一个东西它不需要你自己去计算是否滑到底部,而是在滑动底部自动触发一个Command,同时把当前列表的总共的item数量返回给你,方便你通过 page=itemCount/LIMIT+1去计算出应该请求服务器哪一页的数据那该多好啊。MVVM Light Toolkit 帮你实现了这一点:


public final ReplyCommand onLoadMoreCommand = new ReplyCommand (( itemCount ) ->







请到「今天看啥」查看全文


推荐文章
复利大王  ·  国产美女宁宁
20 小时前
复利大王  ·  三名日本女技师来北京打工被抓
20 小时前
复利大王  ·  保时捷跌下神坛
昨天
笑点研究所  ·  日本有座寺庙,叫做胸罩寺。。。
8 年前
精读  ·  最重要的事,只有一件
8 年前
盖世汽车每日速递  ·  【微课堂】汽车软件工程解决方案(现场实录)
7 年前