因为最近写了了MVVM框架的使用,有兴趣的朋友看看这里谈谈Android框架 MVC、MVP、MVVM的区,用到了DataBinding,所以今天写写它的介绍。
一、什么是DataBinding以及它的发展历程
DataBinding是一个用来解决界面逻辑的Android数据绑定框架,由去年谷歌 I/O大会上随同MVVM框架一同推出。
Paste_Image.png
二、使用DataBinding有什么好处
对于每个Android开发人员来说,每个Activity的findViewById是一种重复、费力且傻瓜式的操作。于是有了很多注解框架来解决这一类问题,如(ButterKnife、Dagger),但是View层的数据解析还是要写。而DataBinding不仅解决了findViewById的重复操作,它的数据解析更是在XML层上解决,因此如果我们使用DataBinding,数据解析就会更快,这也是官网文档说DataBinding能提高解析XML的速度原因。并且使用DataBinding,你会发现代码真的是省了很多,同时它配合MVVM框架的使用更是比MVP框架提高了提高可维护性(解决了MVP大量的手动View和Model同步的问题,提供双向绑定机制)。同时它没有空指针的问题。
三、DataBinding缺点
1.复杂的布局处理起来很困难
2.IDE不够完善
四、如何使用DataBinding
DataBinding的使用如下图所示:
Paste_Image.png
在Module的build.gradle中添加下面代码,注意的是保证Gradle插件版本不低于1.5.0-alpha1
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
...
dataBinding {
enabled true//添加这个
}
}
activity_main
其中 type 属性就是我们在 Java 文件中定义的 User 类。而 name中的User 是类型的变量,然后把它跟布局文件中声明的变量进行绑定。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="com.haijia.mvvp.bean.User" />
<variable
name="user"
type="User" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{String.valueOf(user.id)}" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.realName}" />
</LinearLayout>
</layout>
MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setUser(new User(123,"黄海佳"));
}
}
就是这么简单就搞定了MVVM的框架,但是这里面有很多细节,下面我们谈谈这些细节。
六、注意细节
1. android:text 中只能写" @{...}"的形式
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.name}" />
输出:黄海佳
不能这样写:
<TextView
...
android:text="姓名@{user.name}" />
输出:姓名@{user.name}
不能这样写:
<TextView
...
android:text="姓名+@{user.name}" />
输出:姓名+@{user.name}
2.注意 android:text 中是 String 类型
假如值 user.id 是 int 类型的话,一定要记得转成 String 类型(String.valueOf())
<TextView
...
android:text="@{String.valueOf(user.id)}" />
3.属性的使用(可用表达式):
<TextView
...
android:text="@{user.name}"
android:marginTop="@{true ? @dimen/largeMargin : @dimen/smallMartin}"/>
4.属性的使用(可使用外部静态方法):
如你有一个工具类的方法
public class MyStringUtils {
public static String capitalize(final String word) {
if (word.length() > 1) {
return String.valueOf(word.charAt(0)).toUpperCase() + word.substring(1);
}
return word;
}
}
<!--导入类-->
<import type="android.databinding.utils.MyStringUtils" />
<TextView
...
android:text="@{StringUtils.capitalize(user.name)}"
android:marginTop="@{1>0? @dimen/largeMargin : @dimen/smallMartin}"/>
5.使用资源或者属性时,记得引包
因为用了View属性和Color属性,需要引入包。
<import type="android.view.View" />
<import type="android.graphics.Color"/>
<!--显示-->
<TextView
...
android:visibility="@{true? View.INVISIBLE : View.VISIBLE}"/>
<!--颜色-->
<TextView
...
android:textColor="@{true? Color.RED : Color.YELLOW}"/>
6.自定义绑定类名称注意包名
如果项目结构如下
|--com
|--dataBinding
|--adapter
|--ui
|--CustomView
|--adapter
那么引入包,我们可以写 com.databinding.CustomView也可以写 com.databinding.ui.CustomView,只要在项目包中即可。
<import class="com.databinding.CustomView" />
<import class="com.databinding.ui.CustomView" />
7.XML文件中不能包含< >符号
如果你的项目里面有用到 "< >" 这样的格式,需要转移一下,例如"<"写成"<"
<!--错误写法-->
<data>
<import type="android.databinding.ObservableMap" />
<variable
name="muser"
type="ObservableMap<String, Object>" />
</data>
<!--正确写法-->
<data>
<import type="android.databinding.ObservableMap" />
<variable
name="muser"
type="ObservableMap<String, Object>" />
</data>
7.Null Coalescing 运算符
<!--写法1-->
android:text="@{user.displayName ?? user.lastName}"
<!--写法2-->
android:text="@{user.displayName != null ? user.displayName : user.lastName}"
8.类型别名
如果我们在 data 节点了导入了两个同名的类怎么办?为导入的类添加别名即可
<import type="com.databinding.bean.User" />
<import type="com.databinding.data.User" alias="DetailUser" />
<variable name="user" type="DetailUser" />
暂时就写这些,后面有机会深入研究再分享