android中data binding的使用
来源:互联网 发布:linux diff命令的功能 编辑:程序博客网 时间:2024/06/05 17:22
Android Data Binding介绍
Data Binding是一个MVVM的架构框架,使用Data Binding对于我们开发应用有下面好处:
- 可以直接在layout布局中的xml中绑定数据
- 分离视图与业务逻辑
- 适用于android 2.1以上的版本
搭建Data Binding环境
使用Data Binding需要下面条件:
- gradle1.3 以上
- android studio1.3以上(当然现在都到了2.2了^_^)
在项目的根目录下build.gradle添加dependenncy
为用到 Data Binding 的模块添加插件,修改对应的 build.gradle
需要注意的是,如果studio在2.0版本之后,可以直接在android中添加
dataBinding{ enabled = true }
Data Binding入门
下面我通过一个简单的栗子,来实现业务和逻辑分离,并在不居中直接绑定数据。
新建一个java bean类
public class UserInfo { public String name; public String phone;}
添加layout布局
在layout中绑定数据,我们需要在原本的layout的跟布局中使用layout,并制定其和那个类相关。
另外我们也可以通过import来引入我们的user类对象
注意:java.lang.* 包中的类会被自动导入,可以直接使用
使用DataBindingUtil绑定布局
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);// setContentView(R.layout.activity_main); // 通过DataBindingUtil重新设置布局 ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main); // 创建一个UserInfo,并绑定数据 UserInfo userInfo = new UserInfo(); userInfo.name = "haha"; userInfo.phone = "1234567890"; // setUser方法是根据在xml中通过variable配置的user自动生成的 binding.setUser(userInfo); }
可以看到,系统自动为我们的activity_main布局生成了对应的ActivityMainBinding类,我们也可以自己定义该Binding类的类名
<data class="TestLayoutMain"> <import type="com.example.myapplication.UserInfo" alias="AliasUserInfo"/> <variable name="user" type="AliasUserInfo"/></data>
此时生成的Binding类名获取方式如下:
TestLayoutMain binding = DataBindingUtil.setContentView(MainActivity.this,R.layout.activity_main);
布局中引用user类
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.name}" />
另外,我们也可以使用jdk中提供的数据类型来进行设置,比如:
<variable name="sex" type="String"></variable>
为UserInfo对象添加sex属性
public String sex;
在布局中使用该属性
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{sex}" />
通过引用布局绑定数据
另外我们可以通过include标签来引用我们的指定的布局,并且传入user对象。
创建布局
user_layout.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="com.example.myapplication.UserInfo"/> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@{user.phone}" /> </LinearLayout></layout>
在主布局中引用该布局
接下来,我们需要在主布局中通过include标签,引用到该布局,并且传递我们的user对象。
<include layout="@layout/user_layout" bind:user="@{user}" />
使用类方法
我们也可以在布局中直接使用定义好的类里面的方法
public class DataUtils { public static String changeCharacter(String originalStr) { if (null != originalStr) { return originalStr.toUpperCase(); } return null; }}
在布局中引入当前类
<data> <import type="com.example.myapplication.UserInfo"/> <import type="com.example.myapplication.DataUtils"/> <variable name="user" type="UserInfo"/> </data>
直接调用该类的静态方法:
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{DataUtils.changeCharacter(user.name)}" />
类型别名
如果我们在布局中导入了两个不同包下的UserInfo对象,此时我们到底该使用哪一个呢。其实我们可以通过alias别名来进行设置。
三元运算符
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#ff0000" android:text="@{user.name ?? user.phone}" />
上面@{user.name ?? user.phone}等价于:
user.name != null ? user.name : user.phone
android:visibility="@{user.mIshow ? View.VISIBLE : View.GONE}"
使用资源数据
这里,我们新创建两个颜色资源:
<color name="red">#ff0000</color><color name="blue">#0000ff</color>
在布局中使用:
<plurals name="numberOfSongsAvailable"> <item quantity="one">One song found.</item> <item quantity="other">%d songs found.</item> </plurals>
在布局中使用:
类型转换器
DataBinding也为我们提供了一个类型转换器,当xml中的类型,和需要显示的类型不同的时候,我们只需要在对应的实体类中添加一个@BindingConversion注解即可。
public class UserInfo { public String name; public String phone; public boolean mIshow; public String sex; @BindingConversion public static int convertToString(int color) { switch (color) { case Color.RED: return R.string.red; case Color.BLUE: return R.string.blue; } return R.string.app_name; }}
可以看到,上面我们在text中返回的是int类型,所以这里通过BindingConversion注解进行类型转换。
<variable name="time" type="java.util.Date"/><TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{time}" />@BindingConversionpublic static String convertDate(Date date) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); return sdf.format(date);}
NullPointException的检测
在DataBinding中,会自动为我们避免出现空指针,比如:user.name和user.age,如果user是null,那么user.name会返回null,user.age是int类型,所以默认返回0
集合类型数据的引用
常用的集合:arrays、lists、sparse lists以及maps,为了简便都可以使用[]来访问
- 在UserInfo中增加一个Map集合
public Map<String,Object> map = new ArrayMap<>(3);//添加设置数据userInfo.map.put("hello",111);userInfo.map.put("world","世界");
- 在布局中使用
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text='@{String.valueOf((Integer)user.map["hello"])}' /><TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text='@{user.map["world"]}' />
带Id的View
当我们在布局中为某一个控件增加id时候,DataBinding会自动生成该根据该id自动生成对应的实例,看下面栗子:
<TextView android:id="@+id/dataBindId" android:layout_width="match_parent" android:layout_height="wrap_content" />TestLayoutMain binding = DataBindingUtil.setContentView(MainActivity.this,R.layout.activity_main); binding.dataBindId.setText("hello world");
ViewStub支持
<ViewStub android:id="@+id/my_viewstub" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout="@layout/user_layout" />TestLayoutMain binding = DataBindingUtil.setContentView(MainActivity.this,R.layout.activity_main);binding.myViewstub.inflate();
ViewStub的使用
<ViewStub android:id="@+id/my_viewstub" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout="@layout/stub_layout" />// 注意这里AS可能会标红,可能是支持不好,但是不影响编译和运行binding.myViewstub.getViewStub().inflate();
事件绑定
同时我们可以通过DataBinding来绑定事件到指定的View,看下面的栗子:
<variable name="clickListener" type="android.view.View.OnClickListener" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{user.name}" android:onClick="@{clickListener}" />
我们知道,当在xml布局文件中定义的每一个variable对象,系统都会生成其对应的setXXX方法。
TestLayoutMain binding = DataBindingUtil.setContentView(MainActivity.this,R.layout.activity_main);binding.setClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(), "setClickListener bind click ok", Toast.LENGTH_LONG).show(); } });
监听数据变化
我们知道,很多时候我们的界面是需要实时改变数据的,当然DataBinding也为我们封装好了,看下面的栗子。
- 创建POJO实例
public class UserInfo extends BaseObservable{ public String name; public UserInfo(String name) { this.name = name; } @Bindable public String getName() { return name; } public void setName(String name) { this.name = name; notifyPropertyChanged(BR.name); }}
这里我们需要动态改变name属性
1. 实体类继承自BaseObservable类
2. 为需要动态改变的属性增加get和set方法
3. 在get方法添加@Bindable注解
4. 在set方法中调用notifyPropertyChanged(BR.xx);来通知数据变化,其中xx为需要改变的属性
- 在布局中引用该实体类
<import type="com.detail.pojo.UserInfo" alias="ObserUser"/><variable name="obserUser" type="ObserUser"/><TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{obserUser.name}" />
- 在代码中动态改变属性内容
final com.detail.pojo.UserInfo user = new com.detail.pojo.UserInfo("hello"); binding.setClickListener(new View.OnClickListener() { @Override public void onClick(View v) { user.setName("world"); } }); binding.setObserUser(user);
使用ObservableField监听数据变化
前面我们创建的实体类,需要为属性设置get和set方法并且需要在set方法中通过notifyPropertyChanged来通知数据变化。这样多少有些麻烦,好在系统为我们提供了一系列的ObservableField,如下:
ObservableField,ObservableBoolean,ObservableByte,ObservableChar,ObservableShort,
ObservableInt,ObservableLong,ObservableFloat,ObservableDouble,ObservableParcelable
通过这些封装ObservableField就无需提供get和set方法了。看下面栗子:
- 创建POJO实体类
public class UserInfo extends BaseObservable{ /** * ObservableField,ObservableBoolean,ObservableByte,ObservableChar,ObservableShort, * ObservableInt,ObservableLong,ObservableFloat,ObservableDouble,ObservableParcelable */ public ObservableField<String> name = new ObservableField<>(); public ObservableInt age = new ObservableInt(); public ObservableBoolean isShow = new ObservableBoolean();}
- 创建布局,通过variable标签引用该POJO
<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android"> <data class="CustomeLayout"> <variable name="user" type="com.detail.pojo.UserInfo"/> <variable name="onClickListener" type="android.view.View.OnClickListener"/> </data><LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.name}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.age}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text='@{user.isShow ? "show" : "donotshow"}' /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{user.name}" android:onClick="@{onClickListener}" /></LinearLayout></layout>
- 在代码中动态改变属性
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); CustomeLayout binding = DataBindingUtil.setContentView(MainActivity.this,R.layout.custom_main); final com.detail.pojo.UserInfo user = new UserInfo(); user.age.set(22); user.name.set("hello world"); user.isShow.set(true); binding.setUser(user); binding.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG,"age is :"+user.age.get()+" name is :"+user.name.get()+" isShow is :"+user.isShow.get()); user.age.set(33); user.name.set("yes it changed"); user.isShow.set(false); } }); }
看到了吧,其实同样很简单,google工程师已经为我们封装的很完美了。
参考:
Android官方数据绑定框架DataBinding(一)
Android官方数据绑定框架DataBinding(二)
Android官方数据绑定框架DataBinding(三)
- android中data binding的使用
- Android Data Binding 使用
- Android-MVVM架构-Data Binding的使用
- Android-MVVM架构-Data Binding的使用
- Android-MVVM架构-Data Binding的使用
- Data Binding的使用
- Android Data Binding初次使用
- android-Data Binding入门使用
- Android---Data Binding使用入门
- Android Data Binding使用笔记
- android 的MVVM模型--Data Binding
- WPF中radiobutton 的 data binding方法
- 数据绑定库Data Binding的使用
- 【基础】 Data Binding的简单使用
- Android Data Binding 技术
- Android Data Binding学习
- Android Data Binding
- Android Data Binding
- 两个辅助指针变量挖字符串(4种实现方式)
- C/C++野指针
- 1.mysql bin-log日志基本操作与数据库备份还原
- scipy求一些统计量的p值和分位数
- C Primer Plus学习 十六 函数概述
- android中data binding的使用
- viewpager过渡页
- SQL存储过程返回受影响的行数
- 关于用java实现RMI通信的项目,MeetingRMI
- 2.mysql mysql备份数据与恢复方案
- LeetCode[204] Count Primes
- Eclipse 使用Egit插件通过SSH上传代码到GitHub
- Android SharedPreferences
- UML——构件图、部署图(实现图)