2017-9-5(dataBinding使用)

作者: 721d739b6619 | 来源:发表于2017-09-05 11:03 被阅读72次

    Data binding 在2015年7月发布的Android Studio v1.3.0 版本上引入,

    在2016年4月Android Studio v2.0.0 上正式支持。

    目前为止,Data Binding 已经支持双向绑定了。

    Data Binding 是一个support库,最低支持到Android 2.1(API Level 7+)。

    本篇主要记录databinding项目中经常使用的地方。其他方面可以参照此文本人觉得写得很详细,我也是参照它的:

    Android-Data-Binding-系列-一-详细介绍与使用

    引入databanding

    Paste_Image.png

    xml布局文件写法

    以<layout></layout>标签为根;到时候它会自动生成一个继承ViewDataBinding类的类;如布局文件名为main_layout,生成类名为:MainLayoutBinding

    Paste_Image.png

    View与Bean之间数据绑定

    布局文件是这样的:

    <?xml version="1.0" encoding="utf-8"?>
    <!-- 下面的命名空间需要写,不然下面android属性都不会显示 -->
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
    
        <data>
            <variable
                name="user"
                type="com.wyman.databindingdemo.databindingbean.DataBindingBean"/>
        </data>
    
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <TextView
                android:id="@+id/userName_textview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@{user.name ?? `Default name`}"
                />
    
            <TextView
                android:id="@+id/userAge_textview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@{user.age ?? `Deafault age`}"
                />
    
            <TextView
                android:id="@+id/userDes_textview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@{user.des ?? `Default des`}"
                />
    
            <Button
                android:id="@+id/databindingbean_button"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="更改bean"
                android:onClick="doClick"
                />
    
        </LinearLayout>
    
    </layout>
    

    <data></data>标签是为了关联java bean,DataBindingBean类就是这个bean,name是在布局文件上的名称;view与bean关联通过"@{user.name}";意思是bean的某个属性;

    "@{user.des ?? Default des}"这种写法的意思是当user.des为null时默认为Defauult des

    再看看bean的写法

    public class DataBindingBean implements Serializable{
        private String name;
        private String age;
        private String des;
    
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAge() {
            return age;
        }
    
        public void setAge(String age) {
            this.age = age;
        }
    
        public String getDes() {
            return des;
        }
    
        public void setDes(String des) {
            this.des = des;
        }
    }
    

    没有什么特别与以前写的一模一样,你也可以不实现Serializable;

    看看如何进行数据绑定

    public class DataBindingBeanActivity extends AppCompatActivity {
    
        private ActivityDataBindingBeanBinding binding;
        private DataBindingBean bean;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    //        setContentView(R.layout.activity_data_binding_bean);
            binding = DataBindingUtil.setContentView(this,R.layout.activity_data_binding_bean);
    
            bean = new DataBindingBean();
            bean.setName("testName");
            bean.setAge("testAge");
            bean.setDes("testDes");
    
            //这样将view与bean进行绑定
            binding.setUser(bean);
            binding.databindingbeanButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    changeBean(bean);
                }
            });
        }
    
        /**
         * 这里尝试改变bean,看textview随之改变
         * */
        private void changeBean(DataBindingBean bean) {
            bean.setDes("change testDes");
            bean.setName(null);
            binding.setUser(bean);
        }
    }
    

    ActivityDataBindingBeanBinding是系统自动生成的layout布局文件的一个继承自ViewDataBinding 的类。
    通过 DataBindingUtil.setContentView(this,R.layout.activity_data_binding_bean);就可以获取到该对象。为什么要该对象呢?往下看:
    主要都是通过该类进行数据绑定更改数据的。

    binding.setUser(bean);

    这里就是实现了view与bean之间的关联;

    看看第二种通过BaseObservable监听

    bean部分

    public class DataBindingRecyclerBean extends BaseObservable{
    
        private String dataName;
        private String dataDate;
        private String dataMsg;
    
        @Bindable
        public String getDataName() {
            return dataName;
        }
    
        public void setDataName(String dataName) {
            this.dataName = dataName;
            notifyPropertyChanged(BR.dataName);
        }
    
        @Bindable
        public String getDataDate() {
            return dataDate;
        }
    
        public void setDataDate(String dataDate) {
            this.dataDate = dataDate;
            notifyPropertyChanged(BR.dataDate);
        }
    
        @Bindable
        public String getDataMsg() {
            return dataMsg;
        }
    
        public void setDataMsg(String dataMsg) {
            this.dataMsg = dataMsg;
            notifyPropertyChanged(BR.dataMsg);
        }
    }
    

    这里和上面的bean不同继承了BaseObservable,get方法前面有个注解@Bindable,set方法多了notifyPropertyChange(BR.dataName)
    注意,是先有@Bindable后有notifyPropertyChange(BR.dataName)的,不然BR后面的属性是不会生成

    布局文件没有什么特别

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
    
        <data>
    
            <variable
                name="bean"
                type="com.wyman.databindingdemo.databindingrecyclerview.DataBindingRecyclerBean"/>
        </data>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/listPreferredItemHeight"
            android:orientation="vertical"
            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
            android:paddingStart="?android:attr/listPreferredItemPaddingStart">
    
            <TextView
                android:id="@+id/text1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:text="@{bean.dataName}"
                android:textAppearance="?attr/textAppearanceListItem"/>
    
            <TextView
                android:id="@+id/text2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignStart="@id/text1"
                android:layout_below="@id/text1"
                android:text="@{bean.dataDate}"
                android:textAppearance="?android:attr/textAppearanceListItemSecondary"/>
    
            <TextView
                android:id="@+id/text3"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignStart="@id/text2"
                android:layout_below="@id/text1"
                android:text="@{bean.dataMsg}"
                android:textAppearance="?android:attr/textAppearanceListItemSecondary"/>
    
        </LinearLayout>
    </layout>
    

    再看看adapter

    这里只贴绑定部分,基本上与上种方法一样

     @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            //将数据与itemview绑定
            holder.mItemBinding.setBean(mList.get(position));
    
        }
    

    最后一种@BindAdapter

    一开始一看我还是以为与adapter相关联的,原来非也。直接黏代码

    /**
     * 注解 @BindAdapter 用法
     */
    public class BindAdapterActivity extends AppCompatActivity {
    
        private BindadapterLayoutBinding mBinding;
        private static Context mContext;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mBinding = DataBindingUtil.setContentView(this, R.layout.bindadapter_layout);
            mContext = this;
    
            //往 testName 注值
            mBinding.setTestName("testName");
        }
    
        // 使用注解,无需手动调用此函数
        @BindingAdapter({"testName","error"})
        public static void testBinddingAdapter(View view,String testName,String error){
            String text = "";
            if(TextUtils.isEmpty(testName)){
                text = error;
            } else {
                text = testName;
            }
            Toast.makeText(mContext,text,Toast.LENGTH_LONG).show();
        }
    
        boolean flag = false;
        public void onClick(View view){
            if(flag){
                mBinding.setTestName(null);
                flag = false;
            } else {
                mBinding.setTestName("bindadapter");
                flag = true;
            }
        }
    }
    
    <?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="testName"
                type="String"/>
        </data>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
    
    
            <!-- 当url存在时,会自动调用注解方法,即Utils中得loadImage()-->
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="TextView"
                app:testName="@{testName}"
                app:error="@{@string/app_name}"
                />
            <!-- 此处不能使用mipmap,会编译不过
    
            -->
    
    
            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="更改BindAdapter"
                android:onClick="onClick"
                />
    
    
        </LinearLayout>
    </layout>
    

    这里其实先看布局文件看TextView标签,多了两个自定义属性,是在注解@BindAdapter使用到的,就在那里注解标注写明。

    看看app:testName="@{testName}",@花括号里面的testName是对应上面data标签的testName的,说明这里传入是String类型,对于java里面lang包里面可以省略全类名。

    再看看@BindAdapter

    @BindingAdapter({"testName","error"})里面的testName和error就是对应刚刚说的两个属性的,刚方法是系统自动调用到,当数据改变就会调用到该方法.

    mBinding.setTestName("testName");该方法的出现是由于布局文件的data标签里面的

    <variable
                name="testName"
                type="String"/>
    

    非自定义属性,注意区分

    自己写了个Demo以便遗忘:

    databindingdemo

    相关文章

      网友评论

        本文标题:2017-9-5(dataBinding使用)

        本文链接:https://www.haomeiwen.com/subject/xqfujxtx.html