《高效开发 MVVM 和 databinding 你需要使用的工具.docx》由会员分享,可在线阅读,更多相关《高效开发 MVVM 和 databinding 你需要使用的工具.docx(14页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、阅读本篇大概需要11分钟。相信不少同学已经开始使用MVVM作为自己Android开发架构了,但实际 上,我在使用过程中查阅资料发现,网上有关MVVM的资料并不是很多,这 主要是因为MVVM还是有一定使用门槛的,并且MVVM不一定会帮助你 提高开发效率,可能你需要写的代码更多了,或者说为了你为了让代码保持 Databinding的双向绑定特性,而需要考虑很多业务以外的设计逻辑。我们使 用一个架构或者设计模式,当然是为了更好的开发体验嘛,所以我将给大家介 绍几个实用的第三方库和工具,来帮助大家解决这些问题。1. MVVMLightFMVVMLightJ这个第三方库实际上是对Databinding工
2、具库的一些扩 展,并且通过ReplyCommand和Responsecommand来对所有的View 的事件进行统一封装,这是我认为MVVMLight最大的用处。博客: 源码: s:/github /kelin-Hong/MVVMLightLinearLayoutandroid:orieotationaverticalM android: layodroid:lyoearLayoutkDesign Text13 24 LF: n Civ master: ( ontext 13 24 LF: n Civ master: ( ontext Switch and =layout xalns:andr
3、oid3LinearLayoutandroid: orientations vertical*android :lyMnatch .parent,android: l”out_Might=、rap_content”android:textsFooActivityM /、Dcsgn Text 1324 IF: Civ mastert Context ioconTrt 6 QAdd u 口八q必:令今:、0app “金4 g ”北:鱼写y|layout | data2 Design TextAdd 口目 切:,:印 口】 7 宗:令 中:、U app “暮|孱孱 :9 y |layout | da
4、ta2 DesignDesignText4. MVVM自动代码生成MVVM和MVP这种架构并不一定会让我们代码量减少,每一个界面可能都 要以一种固定的模式创立很多类,那我们为什么不通过一种自动代码生成工具 来通过简单的配置就完成这些类的创立呢,Java完全就可以实现这些功能。 网上有很多用Java实现的自动生成代码的方式,但每个人实现的MVP和 MVVM架构方式都不同,所以自动化代码也会不同,我来展示下我这边使用 的过程吧。我使用的MVVM代码生成工具的主要思路是比拟简单粗暴的,通过一个xml 文件配置一些属性,比方起一个名字,设置一下文件输出的路径,然后在Java 里用字符串拼接和文件流读取
5、的方式来生成模板代码。7. 1pcrt .public S卬 reotDlr - *,/cenxwProcess Him with e*lt ctfe /nMTU9 Z/iavaXWII*r”文传言public Strlitf confi9Dlr - r&t01r MtooU/ej public Striftf RodulcMm MesSe“if9。VApllcetli/AMfOU StudU.ap/COAtets/jr/jk/Coft0 coc,Aq fiU, /Vtrt/MapethWMroltfStudirojts/01lQuott/tMlt/aeduU.conflf.Ml rwdinf
6、 config flU. /Hert/wepofhl/Mroi4$ttfditfojtt/OilOuote/tMU/fixed.croMeU、KBM0O4ivTMltolM/WTrad*public cUt* Mala (pubU static String MwiRftocationjprivate static fMl Strsg AJUJttL hli private static final String AMftOOWXH *-n private ttatK finel String AMCJUM fianeMfiQuration aConfjurationj iadCofif i9
7、uration aActlvltyConf 19urti; iU cenfiFiUiAf rootOlr -j public Strinf arcOir -, public Striftf rctOir - *j/snenxM我们来看一下ReplyCommand怎么用。我们用常见的下拉刷新控件PuIIToRefreshLayout 来举例子。我们知道如果你想自定义一个控件的事件,你需要使用BindingAdapter注 解,比方ImageView通过URL属性直接根据地址下载图片并显示可以这样 写:B indingAdapter(b i nd:ur1【mage”)public static v
8、oid getlnternetlmage(ImageView iv, String userface) Picasso, wi th(iv. getContext(). load(userface), into(iv);)这种情况往往是比拟简单的,因为只是操作一个属性,但我们要自定义某一个 事件该怎么办呢,比方我们要自定义onClick事件,那可能就得写接口了 :B i nd i ngAdapter (set I mageOnC lick)public static void setImageOnC1ick(ImageView imagoVicw, final ImagcOnClickList
9、e ner listener)if (listener != null) imageView. setOnClickListener(v)-(listener. onClick(v);); interface ImageOnClickListener( void onClick(View v);)使用的时候呢,你得在VM中定义一个ImageOnClickListener的成员变量 listener,在里面写具体的onClick实现方法,然后在xml中通过 app:setImageOnClick=nviewModel.listener来绑定这个事件。当然,你可以直接通过android:onCli
10、ck来进行绑定一个VM方法,这里只是实例。看起来好像也不是很麻烦,但是你可能每一个这样的事件,就得定义一个特殊 的接口 ,我们能不能封装一下呢?这就是这两个Command做的事了。通过这两个类封装了各种请求参数数量 和返回值参数数量的回调方法,在使用的时候,只要在泛型里具体指名请求参 数和返回值的类型即可,可以说很方便了。实例,PullToRefreshLayout是一个刷新列表控件,我们通过使用 ReplyCommand监听下拉刷新和上拉加载的监听器是这样写的:BindView(R. id. refresh listview)PullToRefreshLayout pulIToRefresh
11、Layout;BindingAdapter (value = onRefreshCommand, onLoadConunand, requireAll = fa Ise)public static void onRefreshLoadCommand(final PulIToRefreshLayout pulIToRefreshLayout,final ReplyCommand onRefreshCommand,final ReplyCommand onLoadCommand)pulIToRefreshLayout. setOnRefreshListener(new PulIToRefreshL
12、ayout. OnRefreshL istcner () Overridepublic void onRcfresh(PulIToRefreshLayout pulIToRefreshLayout) if (onRefreshCommand != null) onRefreshCommand. execute 0;) Overridepublic void onLoadMore(Pu11ToRefreshLayout pulIToRefreshLayout) if (onLoadCommand != null)(onLoadCommand. execute(););我们使用统一的ReplyCo
13、mmand来处理控件的各种事件,这里使用的是无 参无返回值的最简单的情况,我们在ViewModel和xml中的写法是和之前 的接口差不多的:public final Rep 1yCommand onRefreshCommand = new ReplyCommand() - getPostData (true);public final ReplyCommand onLoadCommand = new ReplyCommand() - getPostData(tr ue);这样,我们所有事件的接口就统一了。Responsecommand和ReplyCommand的区别主要在,ResponseCo
14、mmand是用来定义那种有 返回值的参数的,而ReplyCommand是没有返回值的,具体的使用方法, 大家可以参考上面的链接,作者自己讲的最详细。2. binding-collection-adapterrbinding-collection-adapterj 对所有需要 adapter 的控件进行了封装, 比方一些常用的:ListView、RecyclerView. ViewPager等,通过使用这个 库,我们就不需要再写adapter 了 ,通过databinding的方式,在xml绑 定一些属性,并在ViewModel中对这些属性进行处理即可完成这些控件的处 理,逻辑清晰,代码简单。G
15、itHub : s:/github /evant/binding-collection-adapter下面举一个RecyclerView的例子。我们现在xml中定义一个RecyclerView 控件。我们看到有三个特殊的属性:layoutManager、items. itemBinding ,这里 的layoutManager大家都比拟熟悉了,参数是在开头的import导入的,传 入相关的类名即可。import type=,com. weaponzhi. test. LayoutManagers/)我们先来看一下itemBinding是干什么用的,我们知道有时候列表项是可能 多布局的,那么这个
16、itemBinding就是用来处理每种布局和对应item的 ViewModel的绑定关系的。上述代码的ViewModel中,定义了该 itemBinding。public final On!temBindClass itemBinding = new OnltemBindClassO.map(NoDataViewMode1. class, BR. noData, R. layout, listitem no data).map(11emViewMode1. class, BR. itemVM, R. layout, listitem page);m叩 方法中有三个参数,第一个参数是这个布局的V
17、iewModel ,第三个参数 是这个布局的xml文件,第二个参数这个xml中引入的ViewModel的BR 文件id。这样我们就绑定好了这个列表控件的多布局逻辑了。一个空数据时候 的布局,一个正常返回数据时候的布局。那么我们的数据是如何刷新的呢,这就要用到上面的items这个属性了,在我 们这个例子里,它是这样定义的:public final ObservableList vicwModcls = new ObservablcArrayListOO ;当我们网络请求返回的时候,我们在数据回调里,通过对数据类型的处理,进 行ItemViewModel的构造,最后只需要将构造好的对象一个个添加到
18、这个 ObservableList数据结构中去,界面的刷新工作都在对应的ItemViewModel 里中进行处理,我们刚刚设置的itemBinding在这时候就起作用了 ,当新增 数据的时候,它会先判断这个更新数据的ItemViewModel的数据类型, NoDataViewModel.class 类型的,那么就使用 R.layout.listitem_no_data , ItemViewModel.class 类型的,就使用 o 当然,其他 的数据更新和删除操作,也会因为双向绑定而同步刷新。我们完全从Adapter的繁琐中解放出来了 !3. Databinding support这是一个An
19、droid Studio插件,我们写xml中的一些Databind代码比方 (layout,、xvariable,、等标签的使用还是比拟多的,而且写起来也比拟繁琐,这个插件就是可以帮助你解放双手,只需要在适当的 地方按(Windows是Alt+Enter)即可,从官网盗几张Gif图给大家 感受一下吧。Wrap with activity_main.xml - MyApplicationlO - /AndroidStudioProjects/MyApplication10遂 ? q口国京4 /、金 app n iik a g | siMyApplicationlO app src 门 main
20、- res layout p activity_main.xml x心 Grad-e 40722itAndroid Mode =-nternao5 Design Text w噌 TODO 9 6: Android Monitor TerminalQ Throwable Assertion faded intention Description Dir URL IsMl Event Log 画 Cradle Console. (today 8:06) 19:18 IF: Ui 1-8 Context - no conte tt &图Add tagWrap w-th 0B二ersiwl elKod
21、iflwut-&? Auyoct xnlnsandroid,x droid:o3.2ttionMertisv android : ayoutkdthtmat chlpBrent* android 二youtlheighttmatchlparent J 8uttg,Nron华 id/QOFbuttorr gdzd IwlsdtT.FtchJurw android :iyoutlheightM.wrFcontent,android:textw.*aa 7id:textw,FOOACti5.ty 7,=-QG 百谒O,L?Q2IA7xnl versionzlo= encoding.-utfl8-7v
22、 n Acyout xalns - androidu: 、schemas-android .con、apk、res、android; xmlns “ toolsz “ /scheaas android com-tools; xmlns “ app”:hp“ tschenas andyid - con、apk、reslautov ARelativeLayout androididu:+id、activityjnain- android 二 ayoutlwidthu.9atch_parent: android 二 ayoutlheightu.aatchlparent: androidpadding
23、Boctoa:16dp: androidpaddingLefT-16dp: and roid“paddingRightt16dp- tooks“context,comgithub.shiraji-myapplicationxainActivity.v ATextviewandroid 二 ayoutlwidth-wraFcontent: android 二 ayoutlheiswwraplcon-ent, androidetextu-zleuo World!V ARelativeLayoutvVA 二 ayoutvBuild Variants g Captures 1 7 Structure I ProjectMyAPP=cationlo app ,口 src 口 mainUI1resF?_ayout,actMtylma-n.xm-actMtylma-n.xm- XesDesign Text爆 TODO 永 Android Monitor 闻 Term-na-1 Event Log 回 Grad-e conso-euj9)ui)pporj piojpuv 郭 ppow piojpuv 6/peg J ThrowaEQ ASSQrt-on fa-mon Descr-p-on9r UR.:(36 m-nuss ago) 320 LF
限制150内