引言:
DataBinding是2015年谷歌I/O上提出来的,从字面意思上看就是数据绑定,实际上就是将数据绑定在xml中,并实现及时刷新,听起来就碉堡了,再也没有了findviewbyId,虽然现在很多注解框架也能实现无findviewbyId,但是这样会影响性能,带着好奇的心理今天来学一下DataBinding的使用
使用:
一,环境配置
使用android studio1.3以上版本,现在基本都升到2.2了吧
在gradle中添加
//在android{}里面添加
dataBinding {
enabled = true
}
不需要对着官网那种添加方式,反正我添加了下载不成功,因为官方文档添加依赖并不是最新版本。
二,简单使用
2.1 布局:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="user"
type="com.example.com.testdatabinding.User"/>
<variable
name="myHandler"
type="com.example.com.testdatabinding.MyHandlers"/>
data>
<LinearLayout
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
>
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.name}"/>
<TextView
android:id="@+id/tv_sex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.sex}"/>
<ImageView
android:id="@+id/iv_head"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
bind:imageUrl="@{user.icon}"
/>
<TextView
android:id="@+id/tv_move"
android:layout_width="100dp"
android:layout_height="48dp"
android:gravity="center"
android:layout_gravity="center_horizontal|bottom"
android:text="点击跳转"
android:onClick="@{myHandler.onClickView}"
/>
LinearLayout>
layout>
上面是我demo中MainActivity对应的xml文件,可以看出跟普通布局的不同。
起始根布局为layout ,再也不是以前的ViewGroup,随后是<data>,和布局的根布局。
<data>里面可以使用import标签和variable标签,二者是相同效果的不同实现方式。
方式1:
type="com.example.com.testdatabinding.User"/>
"user"
type="User"/>
方式2:
"user"
type="com.example.com.testdatabinding.User"/>
赋值:
android:text="@{user.sex}"
采用@{变量名.属性名}格式,这里可以采用表达式支持,详细介绍以官方文档为例。可参考http://jcodecraeer.com/a/anzhuokaifa/developer/2015/0606/3005.html,现实项目中运用应该没有那么复杂,毕竟为了代码的可读性考虑也不该写那么复杂。
android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age < 13 ? View.GONE : View.VISIBLE}"
android:transitionName='@{"image_" + id}'
text是将index+1转型之后的String值,可见性,age小于13不可见,反之可见,这些大大简化了代码量,也在一定程度上提升了程序性能。
点击事件:
"myHandler"
type="com.example.com.testdatabinding.MyHandlers"/>
在调用
android:onClick="@{myHandler.onClickView}"
MyHandlers 类
public class MyHandlers {
public void onClickView(View view){
Toast.makeText(view.getContext(), "绑定事件成功", Toast.LENGTH_SHORT).show();
}
}
也可以直接在代码中
binding.tvMove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this,"我感受到点击了",Toast.LENGTH_LONG).show();
}
});
图片加载:
"@+id/iv_head"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
bind:imageUrl="@{user.icon}"
/>
bind:imageUrl这个属性需要我们自己创建
ImageLoadAdaptersss这个类型可以随意,并没有固定格式
public class ImageLoadAdaptersss {
@BindingAdapter("bind:imageUrl")
public static void bindImage( ImageView imageView,String url){
Picasso.with(imageView.getContext()).load(url).into(imageView);
}
}
* Activity中的代码 ———— *
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
User user=new User();
user.setAge(12);
user.setIcon("https://www.baidu.com/img/2016_10_09logo_61d59f1e74db0be41ffe1d31fb8edef3.png");
user.setName("张三");
user.setSex("男");
ActivityMainBinding binding= DataBindingUtil.setContentView(this,R.layout.activity_main);
binding.setVariable(BR.user,user);
binding.setMyHandler(new MyHandlers());
// binding.tvMove.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// Toast.makeText(MainActivity.this,"我感受到点击了",Toast.LENGTH_LONG).show();
// }
// });
}
binding.setVariable(BR.user,user); 设置绑定对象( binding.setUser(user);)
binding.setMyHandler(new MyHandlers()); 设置绑定点击事件
效果:
可以看到赋值,加载图片,点击事件都有了效果。
看看实体类怎么创建吧
package com.example.com.testdatabinding;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
/**
* Created by Administrator on 2016/10/9.
*/
public class User extends BaseObservable{
private String name;
private String sex;
private int age;
private String icon;
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
@Bindable
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
notifyPropertyChanged(BR.sex);
}
@Bindable
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
notifyPropertyChanged(BR.age);
}
@Bindable
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
notifyPropertyChanged(BR.icon);
}
}
继承BaseObservable类,BaseObservable提供了一系列notify函数(其实就是notifyChange和notifyPropertyChanged),前者会刷新所有的值域,后者则只更新对应BR的flag,该BR的生成通过注释@Bindable生成,在上面的实例代码中,我们可以看到两个get方法被注释上了,所以我们可以通过BR访问到它们并进行特定属性改变的notify。(摘自阿布的解释)
跟recylerview差不多,可局部刷新,可全局刷新。
后续会继续学习DataBinding的使用。