Model-View-Presenter(MVP),即模型-视图-表示层,架构被广泛应用于 Android 应用程序,通过引入表示层将视图与表示逻辑和模型分离。Model-View-ViewModel(MVVM),即模型-视图-视图模型,与 MVP 非常相似,视图模型充当增强的表示层,使用数据绑定器保持视图模型和视图同步。通过将视图绑定到视图模型属性上,数据绑定程序可以处理视图更新而无需手动更改数据来设置视图(例如,不用再设置控件 TextView 的setTest() 或者 setVisibility() 属性)。与 MVP 中的表示层一样,视图模型可以很容易地进行单元测试。本文介绍了数据绑定库和 MVVM 架构模式,以及它们在 Android 上协同工作方式。

数据绑定

什么是数据绑定?

在这里插入图片描述

数据绑定是一种把数据绑定到用户界面元素(控件)的通用机制。通常,数据绑定会将数据从本地存储或者网络绑定到显示层,其特征是数据的改变会自动在数据源和用户界面之间同步。数据绑定库的好处

TextView textView = (TextView) findViewById(R.id.label);EditText editText = (EditText) findViewById(R.id.userinput);ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress); editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { model.setText(s.toString()); }}); textView.setText(model.getLabel());progressBar.setVisibility(View.GONE);

如上述代码所示,大量的 findViewById() 调用之后,又是一大堆 setter/listener 之类的调用。 即使使用 ButterKnife 注入库也没有使情况改善。而数据绑定库就能很好地解决这个问题。

在编译时创建一个绑定类,它为所有视图提供一个 ID 字段,因此不再需要调用 findViewById() 方法。实际上,这种方式比调用 findViewById() 方法快数倍,因为数据绑定库创建代码仅需要遍历视图结构一次。

绑定类中也实现了视图文件的绑定逻辑,因此所有 setter 会在绑定类中被调用,你无须为之操心。总之,它能让你的代码变得更简洁。

如何设置数据绑定?

android { compileSdkVersion 25 buildToolsVersion "25.0.1" ... dataBinding { enabled = true } ...}

首先在 app 的 build.gradle 中添加 dataBinding { enabled = true }。之后构建系统会收到提示对数据绑定启用附加处理,如,从布局文件创建绑定类。

 ...

接下来,在 标签中包装下布局中的顶层元素,以便为此布局创建绑定类。绑定类具有和布局 xml 文件相同的名称,只是在结尾添加 Binding,例如, Activity_main.xml 的绑定类名字是 ActivityMainBinding。 如上所示,命名空间的声明也移到布局标记中。然后,在布局标记内声明将需要绑定的数据作为变量,并设置好名称和类型。示例中,唯一的变量是视图模型,但后续变量会增加。你可以选择导入类,以便能使用 View.VISIBLE 或静态方法等常量。

如何绑定数据?

 android:padding="@{vm.bigPadding ? @dimen/paddingBig : @dimen/paddingNormal}" android:text='@{vm.text ?? @string/defaultText + "Additional text."}' />

视图属性上的数据绑定指令以@开头,以大括号结束。你可以使用任何变量在数据段中导入你之前声明的变量。这些表达式基本支持你在代码中的所有操作,例如算术运算符或字符串连接。

Visibility 属性中还支持 if-then-else 三元运算符。还提供了合并运算符 ??,如果左边的值为空,则返回右操作数。在上述代码中,你可以像在正常布局中一样访问资源,因此你可以根据布尔变量的取值选择不同的 dimension 资源,也可以使用 padding 属性查看这些资源。

即使你在代码中使用 getters 和 setters,你所声明的变量的属性也可以用字段访问语法的形式访问。你可以在 slide 上的文本属性中看到此部分,其中 vm.text 调用视图模型的 getText() 方法。最后,一些小的限制也适用,例如,不能创建新对象,但是数据绑定库仍然非常强大。

哪些属性是可以绑定的?

android:text="@{vm.text}"android:visibility="@{vm.visibility}"android:paddingLeft="@{vm.padding}"android:layout_marginBottom="@{vm.margin}"app:adapter="@{vm.adapter}"

实际上,标准视图的大多数属性已经被数据绑定库支持。在数据绑定库内部,当你使用数据绑定时,库按照视图类型查找属性名称的 setter。例如,当你把数据绑定到 text 属性时,绑定库会在视图类中使用合适的参数类型查找 setText() 方法,上述示例是 String。

当没有对应的布局属性时,你也可以使用数据绑定的 setter。例如,你可以在 xml 布局中的 recycleler 视图上使用 app:adapter 属性,以利用数据绑定设置适配器参数。

对于标准属性,不是所有的都在 View 上有对应的 setter 方法。例如,paddingLeft 情况下,数据绑定库支持自定义的 setter,以便将绑定转移到 padding 属性上。但是,遇到 layout_marginBottom 的情况,当绑定库没有提供自定义 setter 时我们要怎么处理呢?

自定义 Setter

@BindingAdapter("android:layout_marginBottom")public static void setLayoutMarginBottom(View v, int bottomMargin) { ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) v.getLayoutParams();  if (layoutParams != null) { layoutParams.bottomMargin = bottomMargin; }}

对于上述情况,自定义 setter 可以被重写。Setter 是使用 @BindingAdapter 注解来实现的,布局属性使用参数命名,使得绑定适配器被调用。上面示例提供了一个用于绑定 layout_marginBottom 的适配器。

方法必须是 public static void ,而且必须接受绑定适配器调用的首个视图类型作为参数,然后将数据强绑定到你需要的类型。在这个例子中,我们使用一个 int 类型为类型 View(子类型)定义一个绑定适配器。最后,实现绑定适配器接口。对于 layout_marginBottom,我们需要获取布局参数,并且设置底部间隔:

@BindingAdapter({"imageUrl

beego model绑定字段找不到_MVVM 架构与数据绑定库相关推荐

  1. ModelBinder——ASP.NET MVC Model绑定的核心

    Model的绑定体现在从当前请求提取相应的数据绑定到目标Action方法的参数.通过前面的介绍我们知道Action方法的参数通过ParameterDescriptor来描述,ParameterDesc ...

  2. ASP.NET MVC Model绑定(二)

    ASP.NET MVC Model绑定(二) 前言 上篇对于Model绑定的简单演示想必大家对Model绑定的使用方式有一点的了解,那大家有没有想过Model绑定器是在什么时候执行的?又或是执行的过程 ...

  3. ASP.NET MVC Model绑定(四)

    ASP.NET MVC Model绑定(四) 前言 前面的篇幅对于Model绑定器IModelBinder以及实现类型.Model绑定器提供程序都作了粗略的讲解,可以把Model绑定器想象成一个大的容 ...

  4. python怎么设置字段_Django Model中字段(field)的各种选项说明

    字段与选项 CharField() 字符字段 max_length = xxx or None # 必选项 blank = True 和 default = '' # 如果不是必填项,可以设置 uni ...

  5. ASP.NET MVC Model绑定小结

    Model绑定是指从URL提取数据,生成对应Action方法的参数这个过程.前面介绍的一系列Descriptor负责提供了控制器,行为方法和参数的元数据,ValueProvieder负责获取数据,剩下 ...

  6. ASP.NET MVC Model绑定(五)

    ASP.NET MVC Model绑定(五) 前言 前面的篇幅对于IValueProvider的获取位置和所处的生成过程做了解说,本篇将会对IValueProvider的使用做个基础的演示样例解说,读 ...

  7. Django中的Model(字段) - 第五轻柔的code - 博客园

    Django中的Model(字段) - 第五轻柔的code - 博客园 Django ORM 中的批量操作 - AlphaJx - 博客园

  8. Flask-admin Model View字段介绍

    Model View字段介绍 can_create = True 是否可以创建can_edit = True 是否可以编辑can_delete = True 是否可以删除list_template = ...

  9. Phoenix查询报错,字段找不到。Error: ERROR 504 (42703): Undefined column. columnName=(state=42703,code=504)

    Phoenix查询报错,字段找不到, 根本原因,单引号和双引号的问题, 对于常量字符串,使用单引号,对于表名,字段名的小写使用双引号!! Error: ERROR 504 (42703): Undef ...

最新文章

  1. python开发需要掌握哪些知识-研究深度学习的开发者,需要对 Python 掌握哪些知识?...
  2. boost::math::legendre_stieltjes用法的测试程序
  3. java如何实现封装_java如何实现封装
  4. java之for循环
  5. linux 端口限速技术,linux下如何实现对每个IP进行限制带宽??
  6. 自动定位失败_自动化测试01
  7. PKU 1062 昂贵的聘礼
  8. 分享一段Excel实用快捷键
  9. matlab sym是什么意思,SYM是什么意思 sym是什么意思
  10. 2020年chx的计算机保研之路系列(5)——夏令营面试问题及感想杂谈
  11. 史上最简单的免费短信验证码案例
  12. Modularity的计算方法——社团检测中模块度计算公式详解(转)
  13. Bootstrap3基础 table-striped 表格实现隔行换色(浅灰色与白色交替)
  14. Pytorch目标检测学习资源
  15. Java面试题(4)
  16. 火狐浏览器和IE的CSS区别
  17. 蔡楚生暨潮籍电影名人史迹馆在广东汕头开馆
  18. PAT 乙级练习 1069 微博转发抽奖
  19. 支持qm/mm的gromacs编译(gromacs+cp2k)
  20. QCustomplot(二) 源码解读

热门文章

  1. leetcode 1399. 统计最大组的数目
  2. mysql悲观锁测试_测试一个mysql 悲观锁
  3. selenium之 autoit命令行参数
  4. android手机上实现竖直seekbar的EQ均衡器
  5. php动态生成链接,如何使用PHP动态生成HTML页面?
  6. 移动阅读市场也需要“小而美”
  7. eds能谱图分析实例_EDS那些事儿
  8. 基础研究与国家目标——国家重点基础研究发展计划[转自科学社]
  9. 安全中心开启小米云服务器,小米云服务使用手册
  10. 在Linux下将PNG和JPG批量互转的四种方法