在上一篇文章Android Databinding(初识),介绍了Databinding及代码示例,在这里将从代码的层次上进行Databinding的详细讲解。
        本章节主要讲解Data binding的xml文件的代码书写规范。下面直接上硬货。

activity_main文件

<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:fresco="http://schemas.android.com/apk/res-auto">    <data>        <import type="wshuttle.com.testmvvm.bean.UserInfo"/>        <import type="android.view.View"/>        <variable            name="imageUrl"            type="android.databinding.ObservableInt" />        <variable name="userInfo" type="UserInfo" >variable>        <variable name="show" type="android.databinding.ObservableBoolean" >variable>        <variable            name="myEventHandler"            type="wshuttle.com.testmvvm.ui.MainActivity.MyEventHandler">variable>        <variable            name="orderInfo"         type="wshuttle.com.testmvvm.bean.OrderInfo" />    data>    <LinearLayout        android:layout_width="match_parent"        android:orientation="vertical"        android:fitsSystemWindows="true"        android:clipToPadding="false"        android:background="@color/bg_color"        android:layout_height="match_parent">        <android.support.v7.widget.Toolbar            android:layout_width="match_parent"            android:layout_height="?attr/actionBarSize"            android:id="@+id/toolbar"            android:background="@color/theme_color">        android.support.v7.widget.Toolbar>      <EditText        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:textColor="@color/text_color"        android:text="@{String.valueOf(userInfo.id)}" />        <EditText            android:cursorVisible="true"            android:textCursorDrawable="@drawable/color_cursor"            android:layout_width="match_parent"            android:textColor="@color/text_color"            android:id="@+id/username"            android:layout_height="wrap_content"            android:text="@={userInfo.name}" />        <EditText            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:textColor="@color/text_color"            android:text="@={userInfo.type}" />        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:textColor="@color/text_color"            android:onClick="@{(view) ->myEventHandler.getUser(userInfo)}"            android:id="@+id/btnGetName"            android:text="获取用户信息" />        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:textColor="@color/text_color"            android:onClick="@{myEventHandler::onClick}"            android:id="@+id/btnGetType"            android:text="获取车主姓名" />        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:textColor="@color/text_color"            android:text="@{orderInfo.orderid}" />        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:textColor="@color/text_color"            android:text="@{orderInfo.rescueName}" />                                                                            <com.facebook.drawee.view.SimpleDraweeView            android:layout_width="50dp"            android:layout_height="50dp"            android:visibility="@{show.get()?View.VISIBLE:View.GONE}"            fresco:image_url="@{imageUrl.get()}"            fresco:roundAsCircle="true"            />        <ImageView            android:layout_width="50dp"            android:layout_height="50dp"            fresco:image_url="@{imageUrl.get()}"        />        <ListView            android:layout_width="match_parent"            android:layout_height="match_parent"            android:paddingTop="16dp"            android:id="@+id/listView"        />    LinearLayout>layout>

        第一眼看去也许跟原先的布局文件与很大变化,但是细看变化之处在于节点的变化,内层的布局与原布局文件是一模一样的。下面针对布局文件中的节点进行解释。

一、layout

        在这里,不是以相对布局等布局方式作为根节点,而是以layout作为根节点,它的作用是申明它是一个data binding的布局文件,申明后as会自动编译生成一个ActivityMainBinding(首字母大写,加后缀Binding)的Java类,我们在Activity操作的实际上就是这个Java类。
        我们先说一说这个根节点下面引入的命名空间,第一个Android就无需解释了,第二个http://schemas.android.com/apk/res-auto是Data binding进行一些数据属性绑定所需要用到的命名空间,fresco只是一个别名而已无需在意,我的建议是每次如果需要把该布局设置成data binding布局的话,根节点上就添加这样一个命名空间,方便之后的调用。

二、data
        此节点是整个布局上最大的变化之处,data节点从字面意思就明白我们数据就在这里了,实际上data节点也就是整个布局文件的数据源,data节点的内容就类似于Java类中引入包以及定义变量的意思。下面说说data下面各个节点的意义。

import:跟Java类一样,就相当于引入Java包,其中有的常用属性有,type:类的路径,需要有包名,alias:为该引入的包去别名(主要为了区分引入两个相同的类名的冲突)。
variable:相当于定义变量,其中常用的属性有,name:变量的名称,type:变量的类型(基本类型,Java类或者Data
bingding类型等)。

        下面就本例子下data节点进行解释,本例子下引入了项目的UserInfo,View;定义了imageUrl类型为ObservableInt,userInfo等变量。在这里解释一下ObservableInt是什么类型呢?这个类型是Data binding中定义的类型,如果你布局文件中定义的是此种类型的话,你在Activity中对这个值进行重新赋值的话,界面上会进行刷新,会在改界面上引用改变量地方进行刷新操作(具体如何操作请看),实际上还有另外一种方式可实现单向的刷新操作,imageUrl的类型可以直接为int类型,但是需要Activity调用Binding类的notifyPropertyChanged方法刷新该数据才会刷新界面,代码如下:

ActivityMainBinding bing = DataBindingUtil.setContentView(this, R.layout.activity_main);bing.notifyPropertyChanged(BR.imageUrl);//刷新imageUrl的value

        综合来讲,data下面就是定义数据的地方,只不过data binding在进行数据绑定时,实行Activity与layout实现界面更新,需要使用它自己内部定义的方法或者说写上刷新界面的方法。注意在引入类的过程中,要注意xml中有些必须转义的字符,比如说引入Map时,你直接使用Map是会报错的,你必须使用下面的方式

 type="Map<String,Object>" />

三、数据以及事件绑定

        这里是layout文件的重点,data binding是如何实现数据的绑定的呢?我们从上面activity_main.xml文件的源码中进行分析。在这里我们可以看见上面三个文本框的text属性的赋值,看之前我们先看看UsInfo类,这里的UserInfo的属性也使用的是Observable类型的类型,也是为了实现一种单向的绑定。看看我们的EditText的赋值操作, android:text=”@{String.valueOf(userInfo.id)}”这里由于id是int类型,我们使用String.ValueOf进行转化为String,否则会报错,text必须是要为String类型,由于两遍的类型不匹配所以这个字段只能支持一种单向的绑定,也就是Activity刷新layout;android:text=”@={userInfo.name}”就是实现的一种双向的绑定,Activity值改变会刷新数据,EditText输入文本以后会改变Activity对应的实体,如此形成绑定以后则无需再关心layout中的标签了。布局中的id与name的绑定就是数据的单向绑定与双向绑定,@{}为单向的绑定,@={}为双向的绑定。

UserInfo

package wshuttle.com.testmvvm.bean;import android.databinding.ObservableField;import android.databinding.ObservableInt;/** * Observable数据基本类型实现绑定@{}:单向绑定,@={}双向绑定,不是String类型实现双向绑定无法绑定,待解决. * Created by yzy on 2016/9/21. */public class UserInfo{    public ObservableInt id = new ObservableInt();    public ObservableField name = new ObservableField();    public ObservableField type = new ObservableField();    @Override    public String toString() {        return "UserInfo{" +                "id=" + id.toString() +                ", name=" + name.toString() +                ", type=" + type.toString() +                '}';    }    public UserInfo(int id, String name, String type) {        this.id.set(id);        this.name.set(name);        this.type.set(type);    }    public UserInfo() {    }}
"match_parent"     android:layout_height="wrap_content"     android:textColor="@color/text_color"     android:text="@{String.valueOf(userInfo.id)}" /> "true"     android:textCursorDrawable="@drawable/color_cursor"     android:layout_width="match_parent"     android:textColor="@color/text_color"     android:id="@+id/username"     android:layout_height="wrap_content"     android:text="@={userInfo.name}" /> "match_parent"     android:layout_height="wrap_content"     android:textColor="@color/text_color"     android:text="@={userInfo.type}" />

        看完EditText的单向绑定以及双向绑定,我们再来看看其他的绑定吧。下面我们看看Data binding的事件绑定,事件的绑定在这里我是使用自定义的MyEventHandler类来处理这个单击事件(在这里我们可以直接使用onClickListener进行单击事件赋值,在这里为了体现一种data binding的可扩展性我使用的是自定义的事件处理),该类中只有两个方法一个getUser方法,参数有一个UserInfo,一个onClick方法,参数View。我们看布局文件中Button,第一个android:onClick=”@{(view) ->myEventHandler.getUser(userInfo)}”,这里使用的是lambda表达式进行事件的绑定,在这里前面的(view)表示的事件本身,myEventHandler是声明的变量,我们调用myEventHandler.getUserInfo的方法来处理该单击事件,并且将userInfo的参数作为形参;第二个button, android:onClick=”@{myEventHandler::onClick}”直接使用调用的方法,由于它无需传递参数,所以这里就使用::调用方法,调用此方法默认是会把本身的view作为参数传递到方法中。注意:如果没有参数的话,自定义的事件监听的方法也必须要有view作为参数传递进去,否则会报错。

myEventHandler

   /**     * 自定义事件Handler     */    public class MyEventHandler {        public void onClick(View view) {            switch (view.getId()) {                case R.id.btnGetType: {                    Toast.makeText(MainActivity.this, orderInfo.getRescueName(), Toast.LENGTH_SHORT).show();                    break;                }            }        }        public void getUser(UserInfo userInfo) {            Toast.makeText(MainActivity.this,"id:" + userInfo.id.get() + ",name:" + userInfo.name.get() + ",type:" +userInfo.type.get() ,Toast.LENGTH_SHORT).show();        }    }
    

        下面我们再看一下,在布局文件中的逻辑判断,这里我们界面上实现的简单的逻辑判断是通过根据show的值显示隐藏图片。 在这里android:visibility=”@{show.get()?View.VISIBLE:View.GONE}”,show是ObservableBoolean类型的,它实际上是一个类,所以通过.get获取它的值,在这里我们可以看见这只是一个简单的?语句操作符,实现了简单的image显示隐藏,实际上可以通过更加复杂的语句进行判断,执行逻辑操作。在这个标签控件下我们还可以看见一个fresco这不是引用的data binding需要的命名空间吗?roundAsCircle是com.facebook.fresco框架(一个比较好的图片框架)自带的属性,但是image_url这明显感觉不像啊,在这里简单说一下,那是我们自己定义的属性,就如同自定义控件的attr一样,自定义属性的方法我们在下一章节进行详细讲解。

   <com.facebook.drawee.view.SimpleDraweeView            android:layout_width="50dp"            android:layout_height="50dp"            android:visibility="@{show.get()?View.VISIBLE:View.GONE}"            fresco:image_url="@{imageUrl.get()}"            fresco:roundAsCircle="true"            />

四、注意点
        1、在xml中使用的过程中,有些重要的字符是需要转义的,比如>、&等等,需要转义的话可以参考Xml文件必须转义的字符。
        2、自定义事件监听时,如果自定义的方法没有参数的话,也需要增加View的形参,否则编译不会通过。
        3、在xml中如果需要直接使用字符串的话,需要使用 ` (英文状态下的tab上一个键)。
        4、在xml中字符赋值过程中,最好不要直接使用字符进行累加显示比如说android:text=”@{你好啊+test+哈哈哈}”,有时会提示utf-8的问题,可能是字符大小超过限制,如果必须要的话最好使用android:text=”@{@string/nihao_string+test+@string/haha_string}”>

五、总结
        在本篇文章中主要讲解的data binding在layout的语法以及结构,看完本章后可以继续查看下一章节(Android databinding详解(二)–activity解析),将具体讲解data binding在activity中的具体讲解。

更多相关文章

  1. android xml解析之pull解析
  2. Android(安卓)中Parcelable的作用
  3. Android中选取并绑定AppWidget
  4. Android(安卓)通过 AccessibilityService 来实现微信自动点赞功
  5. MVVM + dataBinding
  6. android:DataBinding使用小结(一)
  7. Android(安卓)基础知识之JobScheduler基本使用
  8. Android(安卓)Modules 依赖关系,命令行
  9. 认识 Android(安卓)Service

随机推荐

  1. Android中图片的三级缓存策略
  2. 如何在App中实现IM功能之三快速实现离线
  3. Android(安卓)11正式发布:小米、OPPO等手
  4. 从 Android(安卓)到 Java:如何从不同视角
  5. Android传感器编程入门(三)
  6. Android图片缓存分析(一)
  7. Android(安卓)studio 忽略文件不生效
  8. android studio初步体验系列目录
  9. Android表情文字EmotionText解析
  10. 在android下出现乱码的问题(在网络中传输