Android Databinding(一)
2015年12月24日
[TOC]
1、环境需要:
1.Android 2.1 (API level 7+)2.Gradle 1.5.0-alpha13.Android Studio 1.3
2、环境搭建
在build.gradle的android中加入如下字段,等待系统重新编译。
android{ ... dataBinding { enabled = true } ...}
3、快速开始
1、编写布局布局文件
和传统的布局文件不同,databinding的布局文件的跟标签为layout
,他有两个子标签,分别为data
和原始布局标签,也就是说在原来的布局基础上多加了一层layout
,然后里面又多了一个data
标签。在写完布局文件之后别忘记MakeProject一下,以便系统自动生成对应的类,类名为布局文件的名字首字母大写。
<?xml version="1.0" encoding="utf-8"?>
2、编写数据对象
一个简单POJO即可
public class Person { public final String name; public final int age; public Person(String name, int age) { this.name = name; this.age = age; }}
3、在Acticity中进行绑定
在Acticity的onCreate(一个参数)方法里面进行绑定。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //当编写完布局文件的时候,他会自动生成一个对应的类,名字为布局文件名称+Binding ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); Person person = new Person("liucl", 22); //绑定 binding.setPerson(person); }
*** 注意:***编译过中程如果出现xxx.databingding不存在,那么就是你布局文件写错了。仔细检查,现在as还不支持语法提示。
运行正常如下:
quickstart
成功了,就是这三步!!!
4、绑定点击事件
Databinding支持把事件绑定到对象中,使用方法和上面大同小异
1、编写事件对象
public class ClickEvent { public void click(View v){ Toast.makeText(v.getContext(), "测试成功 \n Context对象为" + v.getContext().toString() + "\n View对象为" + v.toString(), Toast.LENGTH_SHORT).show(); }}
在这里我们吐司出v所在Context对象和View对象以及他所属的布局。
2、修改我们的布局文件
首先新建一个variable
引入这个类。在data
字段中加入
其实,我们可以使用import
直接导入这个类,值得注意的是,这个区别于java
的import
关键字,java
中这个是导入包,而这个是导入类。完整的data
代码如下:
之后,我们在布局文件中加入一个Button
,在onClick
属性中引用这个类
最后别忘记在Acticity中绑定!!!
... binding.setEvent(new ClickEvent());...
运行正常如下:
quickstart
5、Include对象传递
Databinding支持include对象传递,在A布局里面的对象可以传递到他include进来的布局,
- 在A布局里定义号自定义命名空间。
xmlns:app="http://schemas.android.com/apk/res-auto"
下面要用到。 - A布局里面的include标签
- B布局代码
在B中也要引用一个传递过来的类,这个布局不用在Acticity中绑定。看过这个代码之后,你可能回想怎么不用merge
优化呢,——暂时不支持
<?xml version="1.0" encoding="utf-8"?>
6、表达式符号
布局文件支持这些表达式,我直接引用谷歌文档
https://developer.android.com/tools/data-binding/guide.html
Mathematical + - / * %String + 这个符号可能会引起引号冲突,需把文字放到资源文件Logical && ||Binary & | ^Unary + - ! ~Shift >> >>> < < >= <=instanceofGrouping ()Literals - character, String, numeric, nullCastMethod callsField accessArray access []Ternary operator ?:
7、绑定对象与视图,使他们能联动
通过更改对象,视图自动就会随之改变,这个功能实现View与model层逻辑代码的解耦和。
谷歌给出两种方法
- Observable Objects
将你的POJO继承BaseObservable,这个类实现了Observable。可以实现POJO值改变,framework层会自动更新布局文件数据
private static class Person extends BaseObservable { private String name; private String age; @Bindable public String getName() { return name; } @Bindable public String getAge() { return age; } public void setName(String name) { this.name = name; notifyPropertyChanged(BR.name); } public void setAge(String age) { this.age = age; notifyPropertyChanged(BR.age); }}
- ObservableFields
其实他继承了BaseObservable这个类,在他的泛型中添上你的类型。同时
ObservableBoolean, ObservableByte, ObservableChar, ObservableShort, ObservableInt, ObservableLong, ObservableFloat, ObservableDouble,ObservableParcelable
也都是继承了BaseObservable。
public class Person { public ObservableField name = new ObservableField<>(); public ObservableInt age = new ObservableInt();}
注:谷歌文档也给了一个Observable Collections,但我没试验成功,但是使用上面那个方法,是可以实现集合更改的。
通过上面的修改后,无论在那里改这个对象里面的值,相应的布局文件里面的引用都会随之改变。
8、抛弃你的findViewById()
有了Databinding
再也不用谢冗长的findViewById()了,框架会为你自动生成的BR文件。
首先在我们的布局文件中,为我们两个TextView
加上id
,回到Acticity中的Binding对象,是不是多出了两个属性。
binding.tvText1.setText(""); binding.tvText2.setText("");
这样你就可以直接给他设置文本了,但是有一种更好的方法,直接binding.setVariable(com.znke.hellodatabinding.BR.person,new Person());
就可以直接给布局文件中的变量赋值。
BR存储了布局中
data
标签中的variable
,相当于R文件。
9、Attribute Setters(属性设置)
这东西就好像Button里面的onClick属性,然后给他在Acticity里面写一个对应的实现方法。他的强大之处就是它可以什么都向里面设置。不关是点击事件。他对于的实现方法只需要用一个注解声明就可以了,写在那里都可以,即使是一个没有使用的java文件。
通过一个Demo来说明,他有一个输入框,输入框输入文字,上面的TextView
也会随之改变,这里用到了属性设置
和对象绑定
。
布局代码
属性设置代码
public class BindingAdapter { private static final String TAG = BindingAdapter.class.getSimpleName(); /** * 添加上这个注解,方法为静态无返回值, * 方法有两个参数,第一个是控件本身,第二个为传进来的对象 * 注意这个方法会被调用多次,其中会有对象为空的情况。So... * * @param e 控件本身 * @param person 传进来的对象 */ @android.databinding.BindingAdapter({"app:textwatcher"}) public static void editTextWatcher(final EditText e,final Person person) { if (person != null) { e.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { person.name.set(s.toString()); e.setSelection(s.length()); } }); } }}
BindingAdapter生命周期所在
在View
所在Activity
的onCreate
方法之后。当然,自定义监听除外
12-21 11:39:51.289 3388-3388/? E/TAG: onFinishInflate: 12-21 11:39:51.295 3388-3388/? E/TAG: onCreate: null12-21 11:39:51.331 3388-3388/? E/TAG: initAdapter: 12-21 11:39:51.331 3388-3388/? E/TAG: initManager: 12-21 11:39:51.333 3388-3388/? E/TAG: onAttachedToWindow: 12-21 11:39:51.338 3388-3388/? E/TAG: onMeasure: 12-21 11:39:51.406 3388-3388/? E/TAG: onLayout: 12-21 11:39:51.429 3388-3388/? E/TAG: onMeasure: 12-21 11:39:51.431 3388-3388/? E/TAG: onLayout: 12-21 11:39:51.433 3388-3388/? E/TAG: onDraw: 12-21 11:39:51.502 3388-3388/? E/TAG: onMeasure:
更多相关文章
- android 快速移动sdCard的文件夹
- Android 子控件高度超出父布局的限制
- Android Studio module里面放switch语句报错 R文件找不到
- java.lang.Exception: 密钥库文件不存在: ~/.android/debug.keys
- Android Studio3.0自定义apk输出路径和文件名
- android开发 使用uses-sdk 导致布局不一样解决
- Android SAX解析xml文件
- android studio无法在可视化页面预览布局文件
- 我的hosts文件