Onelong

分享知识,与你一起进步......
RSS icon Home icon
  • DataBinding

    post by onelong / 2016-12-9 3:56 Friday [android]

    DataBinding主要解决了两个问题:

    • 需要多次使用findViewById,损害了应用性能且令人厌烦 
    • 更新UI数据需切换至UI线程,将数据分解映射到各个view比较麻烦

    DataBinding基本使用包括以下内容:

    • 单纯的摆脱findviewbyid
    • 绑定基本数据类型及String
    • 绑定Model数据
    • 绑定事件
    • 通过静态方法转换数据类型
    • 通过运算符操作数据
    • 自定义Binding的类名
    • 绑定相同Model的操作
    • model变量改变自动更新数据
    • 绑定List/Map等集合数据
    • Observable自动更新
    • Databinding与include标签的结合
    • DataBinding与RecyclerView的结合

    命名规则

    • 布局通过DataBindingUtils.setContentView()加载到代码中,而且会生成对应一个Binding对象,对象名是布局文件文称加上Binding后缀
    • 通过Binding对象.id名称,就相当于拿到了指定的布局中的id的控件了,使用起来和findviewbyid获取的控件是一样的
    • 在布局中是通过@{}来绑定数据的,{}中是布局中该控件属性对应的数据类型数据,同时还可以支持运算符运算和静态方法调用和转换
    binding设置数据有2中方式:
    1.binding.setUser(user) 
    2.binding.setVariable(BR.user,user)–采用BR指
    1.android:onClick="@{event.click1}"
    2.android:onClick="@{event::click2}"
    3.android:onClick="@{()->event.cilck3(title4)}"
     [注]:()->event.cilck3(title4)是lambda表达式写法,
     也可以写成:(view)->event.cilck3(title4),前面(view)表示onClick方法的传递的参数,
     如果event.click3()方法中不需要用到view参数,可以将view省略。
     当然event.click1也可以写成(view)->event.click1(view),将onClick(View view)的view参数传递给event.click1(view)方法。
    大概就这意思,以下是伪代码
    onclick(View view){
         event.click1(view)
    }
    <?xml version="1.0" encoding="utf-8"?><!--布局以layout作为根布局-->
    <layout>
    
        <data>
            <!--绑定基本数据类型及String-->
            <!--name:   和java代码中的对象是类似的,名字自定义-->
            <!--type:   和java代码中的类型是一致的-->
            <variable
                name="content"
                type="String" />
    
            <variable
                name="enabled"
                type="boolean" />
                <!--绑定Model数据2中形式,一中是导入该类型的,一种指定类型的全称,和java一样-->
            <!--  方式一 -->
            <variable
                name="user"
                type="www.zhang.com.databinding.User" />
            <!--  方式二 -->
            <!--<import type="www.zhang.com.databinding.User" />-->
            <!--<variable-->
                <!--name="user"-->
                <!--type="User" />-->
        </data>
        <!--我们需要展示的布局-->
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <!--绑定基本数据类型及String的使用是通过   @{数据类型的对象}  通过对应数据类型的控制显示-->
            <Button
                android:id="@+id/main_tv2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:clickable="@{enabled}"
                android:text="@{content}" />
           <Button
                android:id="@+id/main_btn3"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@{user.text}" /><!--这里user.text相当于user.getText()-->
        </LinearLayout>
    </layout>
    <data>
         <variable
                name="user"
                type="www.zhang.com.databinding.User" />
    
            <!--调用静态方法,需要先导入需要的包    当然java中的lang包可以不用导包-->
            <import type="www.zhang.com.databinding.Utils" />
    
        </data>
        android:text="@{Utils.getName(user)}" /><!--就和java中写代码一样,只要符合数据类型就好-->
        
        public class Utils {
        public static String getName(Object o) {
            return o.getClass().getName();
        }
    }
    
            android:paddingLeft="@{user2.state ? @dimen/largepadding : (int)@dimen/smallpadding}"
            android:text="@{user2.content ?? @string/app_name}" />
            <!-- android:text="@{user2.content ?? @string/app_name}"
             等价于
             android:text="@{user2.content!=null? user2.content : @string/app_name}"-->
             android:text="@{`Hello World`+ @string/app_name}" /><!--``字符包裹的表示字符串,可用作拼接字符串 -->
    
     <data class="www.zhang.com.databinding.activity.Item">
        ...
    </data>
    import www.zhang.com.databinding.activity.Item;
    Item binding = DataBindingUtil.setContentView(FiveActivity.this, R.layout.activity_five);
    
    
    
    <data class=".Item">
        ...
    </data>
    import www.zhang.com.databinding.Item;
    Item binding = DataBindingUtil.setContentView(FiveActivity.this, R.layout.activity_five);
    
    
    <data class="Item">
        ...
    </data>
    import www.zhang.com.databinding.databinding.Item;
    Item binding =DataBindingUtil.setContentView(FiveActivity.this, R.layout.activity_five);
    
    <!--因为type="User"都为User类,会导致不知道到那个包,所以可以通过alias属性重命名type的类型,但实际上alias被指定的那个类型(如:www.zhang.com.databinding.model.User)-->
            <import type="www.zhang.com.databinding.model.User" alias="Model"/>
            
     
    Model类继承BaseObservable,BaseObservable实现Android.databinding.Observable接口,Observable接口可以允许附加一个监听器到model对象以便监听对象上的所有属性的变化。
    Observable接口有一个机制来添加和删除监听器,但通知与否由开发人员管理。为了使开发更容易,BaseObservable实现了监听器注册机制。DataBinding实现类依然负责通知当属性改变时。这是通过指定一个Bindable注解给getter以及setter内通知来完成的。
    notifyPropertyChanged(BR.参数名)通知更新这一个参数,需要与@Bindable注解配合使用。notifyChange()通知更新所有参数,可以不用和@Bindable注解配合使用
    
    Observable是一个接口,它的子类有BaseObservable,ObservableField,ObservableBoolean, ObservableByte, ObservableChar, ObservableShort, ObservableInt, ObservableLong, ObservableFloat, ObservableDouble, and ObservableParcelable,ObservableArrayList,ObservableArrayMap
    
    泛型的支持会在编译时期报红线,是可以直接运行的,但是需要通过转义字符才行,如:\<数据类型> 或者\<数据类型\>
    android:text="@{list[1]}"
    android:text="@{map[`name`]}" 
    android:text="@{arrays[0]}"
    
    <include
                android:id="@+id/toolbar"
                layout="@layout/toolbar"
                android:layout_height="56dp"
                android:layout_width="match_parent"
                bind:content="@{con}" />
     <!--通过命名空间将写有toolbar的xml文件中定义的content对象作为属性绑定con对象,这2个对象是同一个类-->

    引用地址:
     

    我要评论