DataBinding框架初体验
转载请附上链接 (http://blog.csdn.net/sinat_17314503/article/details/51711319)
使用前的准备
确保你的 Android 的 Gradle 插件版本不低于 1.5.0-alpha1:
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
}
然后在你自己的每一个Moudle都需要加上
android {
.......
dataBinding {
enabled = true
}
}
然后可以进行框架的使用
首先写一下xml文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<!-- 在定义Variable 在 data 节点中声明一个 User 类型的变量 user-->
<variable name="user" type="com.example.administrator.databinding_demo.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"/>
</LinearLayout>
</layout>
在定义Variable 在 data 节点中声明一个 User 类型的变量 user
以下是User类
public class User {
public final String firstName;
public final String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
最后进行数据绑定
// 因为你的xml是main_first MainFirstBinding 类是自动生成的,所有的 set 方法也是根据 variable 名称生成的
MainFirstBinding bing = DataBindingUtil.setContentView(this, R.layout.main_first);
// 填充数据
User user = new User("韩梅梅","李磊");
// 绑定数据
bing.setUser(user);
这样就完成了DataBinding的最简单的应用
其他方法的获取ViewDataBinding类型
MainActivityBinding binding = MainActivityBinding.inflate(getLayoutInflater());
添加点击事件
设置一个点击的类
public class hand {
public void onClickName(View view) {
System.out.println("233333333333333");
}
public void onClickmore(View view) {
System.out.println("78956");
}
}
在上面xml文件上写下
<variable
name="hand"
type="com.example.administrator.databinding_demo.hand"/>
然后需要去绑定点击事件
在MainActivity里面进行
// 绑定点击事件
hand hand = new hand();
bing.setHand(hand);
可以引入多个元素 在之间
<import type="android.view.View"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:text="@{user.lastName}"
android:onClick="@{hand.onClickName}"
android:visibility="@{user.isvisit ? View.VISIBLE : View.GONE}"/>
根据false true来判断是否显示
显示字符串
xml文件引入 <variable name="string" type="String"/>
<TextView
android:clickable="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{hand.onClickmore}"
android:text="@{string}"/>
在MainActivity中绑定数据 bing.setString("哈哈哈哈");
如果多个类冲突的时候怎么办
例如这样
<import type="com.example.administrator.databinding_demo.User"/>
<import type="com.example.administrator.databinding_demo.alias.User"/>
你可以对其中一个进行别名
这样的 <import type="com.example.administrator.databinding_demo.alias.User" alias="useless"/>
可以进行static的导入
静态方法
public class MyStaticClass {
public static String showmess(String mess){
return mess;
}
}
xml文件导入
<import type="com.example.administrator.databinding_demo.MyStaticClass"/>
不要这样写因为报错了
<variable name="qer" type="MyStaticClass"/>
使用
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{MyStaticClass.showmess(user.lastName)}"/>
使用data的别名
<data class = "test">
</data>
在MainActivity变成这样
test bing = DataBindingUtil.setContentView(this, R.layout.main_first);
这样的话
<data class = "test">
</data>
变成这样
com.example.administrator.databinding_demo.test bing = DataBindingUtil.setContentView(this, R.layout.main_first);
这样的话
<data class = "com.test">
</data>
变成这样
com.test bing = DataBindingUtil.setContentView(this, R.layout.main_first);
以下这段是引用
在模块封装包的databinding包中会生成名为ContactItem的Binding类。如果要想让该类生成在不同的包种,你需要添加前缀.,如下:
<data class=".ContactItem">
...
</data>
在这个情况下,ContactItem类直接在模块包种生成。或者你可以提供整个包名:
<data class="com.example.ContactItem">
...
</data>
Include
通过使用application namespace以及在属性中的Variable名字从容器layout中传递Variables到一个被包含的layout:
不明白什么意思,但还是实践一下 实践出真理
xml文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="com.example.administrator.databinding_demo.User"/>
<variable name="user" type="User"/>
</data>
<LinearLayout
android:layout_width="100dp"
android:layout_height="100dp"
>
<Button
android:text="@{user.lastName}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</layout>
然后再主xml文件中
<include layout="@layout/layouttest"
bind:user = "@{user}"/>
<include layout="@layout/layouttesttwo"/>
</LinearLayout>
效果出现后 哦 原来是值得传递
注意 如果include中 写有这个bind:user = "@{user}"
那么被include的那个必须有user属性 否则报错
以下是引用
表达式
常用表达式跟Java表达式很像,以下这些是一样的:
数学 + - / * %
字符串连接 +
逻辑 && ||
二进制 & | ^
一元运算 + - ! ~
移位 >> >>> <<
比较 == > < >= <=
instanceof
分组 ()
null
Cast
方法调用
数据访问 []
三元运算 ?:
示例:
android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age < 13 ? View.GONE : View.VISIBLE}"
android:transitionName='@{"image_" + id}'
缺少的操作:
this
super
new
显式泛型调用
Null合并操作
?? - 左边的对象如果它不是null,选择左边的对象;或者如果它是null,选择右边的对象:
android:text="@{user.displayName ?? user.lastName}"
函数上的写法如下:
android:text="@{user.displayName != null ? user.displayName : user.lastName}"
这个框架的特殊效果
避免 NullPointerException
Data Binding代码生成时自动检查是否为nulls来避免出现null pointer exceptions错误。例如,在表达式@{user.name}中,如果user是null,user.name会赋予它的默认值(null)。如果你引用user.age,age是int类型,那么它的默认值是0。
使用集合
<!--引入集合-->
<!-- 不懂第一个什么类没写-->
<import type="android.util.SparseArray"/>
<import type="java.util.Map"/>
<import type="java.util.List"/>
<variable name="list" type="List<String>"/>
<!--<variable name="sparse" type="SparseArray<String>"/>-->
<variable name="map" type="Map<String, String>"/>
<variable name="index" type="int"/>
<variable name="key" type="String"/>
</data>
这里注意的一点是<String>
这里用了转义字符 <>这样的是不行的 对xml来说有特殊含义
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{list[index]}"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{map[key]}"/>
// 绑定集合数据
List<String> list = new ArrayList<>();
list.add("wu");
list.add("2");
Map<String,String> map = new HashMap<>();
map.put("1","666");
map.put("2","2333");
bing.setList(list);
bing.setMap(map);
bing.setKey("2");
bing.setIndex(1);
以下是引用
字符串
当使用单引号包含属性值时,在表达式中使用双引号很容易:
android:text='@{map["firstName"]}'
使用双引号来包含属性值也是可以的。字符串前后需要使用"`":
android:text="@{map[`firstName`]}"
android:text="@{map["firstName"]}"
引用资源
这样就可以了
<ImageView
android:background="@{user.isvisit ? @drawable/test : @drawable/ic_launcher}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
以下是引用
格式化字符串和复数可以通过提供参数来判断
android:text="@{@string/nameFormat(firstName, lastName)}"
android:text="@{@plurals/banana(bananaCount)}"
当复数需要多个参数时,所有的参数都会通过:
全选复制放进笔记
Have an orange
Have %d oranges
android:text="@{@plurals/orange(orangeCount, orangeCount)}"
一些资源需要显式类型判断:
类型 | 正常引用 | 表达式引用 |
---|---|---|
String[] | @array | @stringArray |
int[] | @array | @intArray |
TypedArray | @array | @typedArray |
Animator | @animator | @animator |
StateListAnimator | @animator | @stateListAnimator |
color int | @color | @color |
ColorStateList | @color | @colorStateList |
参考
https://segmentfault.com/a/1190000002876984
https://github.com/LyndonChin/MasteringAndroidDataBinding
还有官方文档