使用场景:

在一个列表中,展示输入框。

当列表单个item数量足够多的时候,Edittext在看不到的时候,会被回收。

而,此时在输入框中的数据也会随之而消失。

正常情况下,在列表的适配器adapter中给EdtiText设置一个tag值,并对输入框进行监听,如果有值就储存再map中。

        然后再item显示的时候判断是否有tag值,有的话获取这个对象,给对象赋值。

理论上说,这样是行得通的,但是当列表不止一个的时候,当界面切换太快的时候,当……总之,不是万无一失的。

       而对于程序来说,有时候不是万无一失,就是死亡,不能忍受。

使用方法

dataBinding双向绑定。

       在讲这个之前,先讲述一下databinding的基本用法。


dataBinding {
    enabled true
}

对,就这一句,放到build.gradle中,Android{}下。

xml文件的写法发生了一些变化,不再<LinearLayout 开头,而是

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="index"
            type="com.yarui.app.client.ui.fragment.Index2Fragment" />
    </data>

    <LinearLayout
        android:id="@+id/linear"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/F1F1F1"
        android:fitsSystemWindows="true"
        android:gravity="center_horizontal"
        android:orientation="vertical">


下边可以继续按照以前的写法去铺界面,使用databinding最简单的好处是: 不再findVIewById(R.id.linear) ,也不用使用butterknife自动生成。

而是使用谁都可以.id然后直接使用。

在fragment中加载databinding  xml文件的方法:


indexBiding = DataBindingUtil.inflate(LayoutInflater.from(getActivity()), R.layout.fragment_index2, container, false);
indexBiding.setIndex(this);
setContentView(indexBiding.getRoot());

activity加载databinding xml布局的方法:

tourBinding = DataBindingUtil.setContentView(this, R.layout.activity_tour);
tourBinding.setTour(this);


xml布局在写完之后,activity中命名是规定好了的,

        比如fragment_index2的对象  FragmentIndex2Binding

activity_tour的对象  ActivityTourBinding


*************************************************************

第二点,id的引用:

比如在fragment_index2中使用了一个LinearLayout的Id是linear

        引用这个id的方法: fragment.linear就可以了。


*************************************************************

第三点(重点),bean类值的引用

记得在xml布局的时候<data></data>中有


<data>
        <variable
            name="index"
            type="com.yarui.app.client.ui.fragment.Index2Fragment" />
    </data>

name  就是Index2Fragment得使用对象。

当对象是一个类,那么这个类里得所有方法,都可以使用index.方法名()来实现

前提: 类的方法中需要有一个固定参数(View view)

比如,Index2Fragment 中有一个方法setInfo(View view),需要在xml布局中直接调用,

那行代码:


android:onClick="@{index.setInfo}"

当对象是一个类,自己封装的实体类:


public class BundleInfo implements Serializable {
    private int error;
    private String errorCode;
    private String msg;//自己添加一些set  get方法,这占地方了。
}

当xml布局调用的时候,在<data></data>中声明一个引用即可,就像index2fragment一样

<data>

<variable

name="bean"

type="BundleInfo"

/>

</data>

需要bundleinfo的值的时候:

Android:text=@{bean.msg}

即可引用这个对象的值

当然,仅仅是在xml布局中申请这个值是没用的,需要有绑定的操作才可以产生绑定的关系。

比如bean是在fragment_index2的布局中引用的,就需要fragment_index2的对象fragment.setBean(BundleInfo的对象)即可



*************************************************************

双向绑定:

当列表recyclerView的item是一个EdtiText的时候,这时候,需要

1 自己封装一个bean类,bean类中只有一个String类型的字符串就行。

2 在recyclerView的适配器adapter加载item布局的时候,声明这个bean类,


android:text="@={bean.taskCardid}"


这样做的用处: 当editText有值的时候,会自动给bean的taskCardId赋值,recyclerView的item因为滑动消失的时候,这个值依然存在。

当recyclerView的EditText显示的时候,这一行代码的作用就是: 给输入框赋值。