我先说一下我公司的情况,然后再说对android databinding的认识
记得去年6月份,我们公司开发的项目(主要是针对餐饮的)走进了市场,遇到了一些问题。客户都说我们产品虽然有一定的好处,但不够便捷,如果能有一个点餐系统来配合使用,一定会更好的。
公司一直遵循客户是上帝,于是苦逼的工作自然就落到了我们开发部的头上了。于是就收集资料,模仿别人现有的产品----食通天,根据别人的成熟产品,自己定需求,定好需求,设计好数据库,接下来的时间就是考虑要用什么语言来开发了,于是在领导的光明指导下,说“那就用C#”来开发吧!
按理说,使用什么语言来开发都是没有什么问题的,谁叫咱是开发部呢?可是现在面临着这么一个问题,我们部门比较小,总人数就10人,其中包括3个测试,3个java,1个安卓,1个iOS,一个UI,一个项目经理,一个产品经理。另外,测试、UI、产品经理、项目经理是不进行开发的。那就仅剩3个java和1个android、1个iOS了。有没有发现什么?没错,我们都不是做C#的,没有一个人接触过C#,于是iOS走了,项目经理也走了。那只能剩下苦逼的我android和3个java了。于是就学呗,用一个星期的时间了解了C#,发现C#其实跟java差不多,语法基本都一样,容易理解。好吧,懂得基本情况,就开发呗!
好吧,开干!!在进行点餐系统的开发过程中,我发现了一个在android领域中还没有引入的框架:MVVM。对,你没有看错,就是MVVM,它是一种采用数据绑定的一种开发模式,可以完美的把视图xaml、数据、业务逻辑进行完美的解耦。这个点餐系统的项目,完美经历了4个月的加班加班加班,终于完工了,但整个项目所使用到的技术中给我印象最深刻的是C#的数据绑定这模块,自此,我对数据绑定有了初步的概念。
好了,闲话已经说了不少了,开始说说我们的android吧
去年的Google IO 大会上,Android 团队发布了一个数据绑定框架(Data Binding Library) 。以后可以直接在 layout 布局 xml 文件中绑定数据了,无需再 findViewById 然后手工设置数据了。其语法和使用方式和 JSP 中的 EL 表达式非常类似。但由于,可能当时我在做C#开发,无暇顾及android的情况,直到今年初,我没有那么忙时,才发现了android已经开始可以使用数据绑定了。
那么,在android上如何使用databinding的呢?
使用步骤(开发工具android studio):
1.配置buid.grade文件
2.定义数据实体
3.布局文件中声明实体,绑定控件
4.java代码引用,填充实体
1.配置buid.grade文件。在module的android下添加如下代码:
dataBinding{
enabled=true
}
2.定义数据实体
package com.example.databinding.bean;
/**
* Created by h on 2016/9/8.
*/
public class User{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
3.布局文件中声明实体,绑定控件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="user"
type="com.example.databinding.bean.User"/>
</data>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.name}"
/>
</LinearLayout>
</layout>
4.java代码引用,填充实体
package com.example.databinding;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.example.databinding.bean.User;
import com.example.databinding.bean.ViewModel;
import com.example.databinding.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
User user=new User();
user.setName("huangxuanheng is very good");
binding.setUser(user);
}
}
上述代码运行后,效果如下图:
![效果图1](https://img-blog.csdn.net/20160909110732918)
小结:
在布局文件中,根节点是layout,如果要绑定数据实体,则要在data节点下声明,data节点下的variable节点,就是用来声明所有引用的数据实体对象和类别的,其中name属性是声明对象实例,type属性声明对象类型,控件中要想引用data中声明的实体对象,可以通过@{对象.属性}引用,如上例中的TextView关于text属性的声明 android:text="@{user.name}"
此时,如果实体对象的属性值发生了改变,界面会不会改变呢?答案是否定的,但实际工作中,我们往往有这样的需求:实体对象的属性改变了,界面也要跟着改变,此时,应该怎么做呢?
android里面提供了一个非常好的一个类BaseObservable,只需要实体类基础了该类,并且在属性发生改变的时候,notify一下,获取属性的方法上标明注解 @Bindable,就可以通知到界面改变了,大致代码如下:
public class User extends BaseObservable {
private String name;
private int age;
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
@Bindable
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
notifyPropertyChanged(BR.age);
}
}
BR不用理它是什么,个人认为相当于R文件中的R,自动生成的,意思是提醒界面改变对应的属性值
android的数据绑定通知方面,感觉是有点复杂的,通过以上这种方式可以达到单向通知界面。在C#的开发过程中,我发现里面的数据绑定的定义非常简单方便,并且关于双向绑定的定义也是非常简单的,只需在xaml文件里面定义,就可以轻松的实现双向绑定了。so~!这方面还有待android进行优化
开发中,往往涉及到点击事件,关于点击事件以往的做法,都是通过findViewById,然后再setOnClickListener实现的,现在有了databinding,关于findViewById的事,自然就不会再用了,那要怎么做呢?
其实很简单,使用规则跟实体绑定类似的,只需在一个类里面编写一个点击的方法,然后在布局中data节点下,新增该类型的对象,在控件的onClick属性中调用该方法就可以了如: android:onClick="@{activity.onTxClick}",示例代码如下:
布局:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="user"
type="com.example.databinding.bean.User"/>
<variable
name="activity"
type="com.example.databinding.MainActivity"/>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:layout_centerInParent="true"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="36sp"
android:text="@{user.name}"
android:onClick="@{activity.onTxClick}"/>
</RelativeLayout>
</layout>
activity:
package com.example.databinding;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.example.databinding.bean.User;
import com.example.databinding.bean.ViewModel;
import com.example.databinding.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
User user=new User();
user.setName("huangxuanheng is very good");
binding.setUser(user);
binding.setActivity(this);
}
public void onTxClick(View view){
Toast.makeText(this,"ni hao a ",Toast.LENGTH_SHORT).show();
User user = binding.getUser();
user.setName("huangxianheng you are a good man!");
}
}
搞定,此时点击后,就可以看到弹出吐司了
以上就是我对android databinding的初步认识,采用了MVVM框架,可以很好的将业务和视图进行解耦。有了databinding,android技术上将更上一层楼,但目前还在不断的改进,API可能随时有改动,使用时切莫要谨慎了!