使用场景:
在一个列表中,展示输入框。
当列表单个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显示的时候,这一行代码的作用就是: 给输入框赋值。