欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

databingding的一些总结

程序员文章站 2022-07-12 10:52:31
...

1.变量:

<variable
            name="user"
            type="User"/>
        <variable
            name="userList"
            type="List&lt;User&gt;"/>
        <variable
            name="handlers"
            type="com.m.databindingdemo.model.MyHandlers"/>
        <variable
            name="task"
            type="com.m.databindingdemo.model.Task"/>
        <variable
            name="present"
            type="com.m.databindingdemo.present.Present"/>

 所有的需要用到的变量,都需要在binding中绑定才可以使用

val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        var user = User("Test", "User", true)
        binding.user = user
        binding.handlers = MyHandlers()
        binding.task = Task()
        binding.present = Present()

 字符串引用:

如果出现有字符串和变量名称一样的,需要加双引号或者单引号:

android:text='@{map["firstName"]}'

android:text="@{map[`firstName`}"
android:text="@{map['firstName']}"

 

2.引用包:

<import type="android.view.View" />
        <import type="com.m.databindingdemo.model.User" />
        <import type="java.util.List" />
        <import type="com.m.databindingdemo.util.MyStringUtils" />
        <import type="android.graphics.drawable.Drawable" />

<variable
            name="image"
            type="Drawable"/>
        <variable
            name="note"
            type="String" />
。。。

 

3.引用&调用:

变量:

android:text="@{user.firstname}"

 调用:

android:onClick="@{handlers::onClickFriend}"
android:text="@{MyStringUtils.capitalize(user.lastname)}"

 调用控件方法:

android:onClick="@{(view) ->present.onSaveClick(view,task)}"
android:onCheckedChanged="@{(cb, isChecked) -> present.onCompletedChanged(cb
,task,isChecked)}"
android:onLongClick="@{(view) -> present.onLongClicked(view,task)}"

可以看出,用的其实也就是控件的接口方法,不过使用了lamda表达式:(接口传入的参数)->要调用的方法 

 

4.include layout:

<include layout="@layout/name"
            bind:user = "@{user}"/>

        <include layout="@layout/contact"
            bind:user = "@{user}"/>

 其他layout:

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="user"
            type="com.m.databindingdemo.model.User"/>
    </data>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.firstname}"
            />
    </LinearLayout>
</layout>

 这样的操作,是可以把user类传给include进来的layout

 

5.表达式:

字符拼接:

'@{"layout" + user.firstname}'

Null Coalescing Operator:

android:text='@{"layout " + user.displayName ?? user.lastname}'

  *如果左面非空,则显示左面,否则右面

 

6.资源引用:

android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"

 string:

<string name="name_format">%1$s name format %2$s </string>

 

android:text='@{@string/name_format(user.firstname,user.lastname)}'

 plurals:

 <plurals name="song">
        <item quantity="one">One song found.</item>
        <item quantity="other">%d songs found.</item>
    </plurals>
android:text="@{@plurals/song(1)}" //单数  
android:text="@{@plurals/song(2,3)}" //复数

 *第一个参数为数量,第二个为替换占位符的字符

 

7.Observable Objects 

Kotlin中field的get/set方法与java不一样,所以不用@Bindable,而用ObservableFields 

class User {
    var firstname: ObservableField<String> = ObservableField()
    var lastname: ObservableField<String> = ObservableField()
    var isAdult: ObservableBoolean = ObservableBoolean()
    var displayName: ObservableField<String> = ObservableField()
}

 必须要先初始化

赋值:必须要使用set method

var user = User()
user.firstname.set("firstname")
user.lastname.set("lastname")
user.displayName.set("displayname")
user.isAdult.set(true

 

 8.Observable Collections

var map: ObservableArrayMap<String, Any> = ObservableArrayMap()

 *kotlin的Any相当于Java的Object

赋值:

//Observable Collection
user.map["firstName"] = "Google"
user.map["lastName"] = "Inc."
user.map["age"] = 17

 layout:

<import type="android.databinding.ObservableMap" />
<variable
            name="obMap"
            type="ObservableMap&lt;String, Object&gt;"/>

 

<TextView
            android:text='@{obMap["lastName"]}'
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:text='@{String.valueOf(1 + (Integer)obMap["age"])}'
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

 不要忘记绑定databinding:

binding.obMap = user.map

 

 ObservableArrayList:

var obList: ObservableArrayList<Any> = ObservableArrayList()
user.obList.add("Google")
user.obList.add("Inc.")
user.obList.add(17)
object Fields {

    const val FIRST_NAME = 0
    const val LAST_NAME = 1
    const val AGE = 2
}

layout:

 <import type="com.m.databindingdemo.model.Fields"/>
 <import type="android.databinding.ObservableList"/>
<variable
            name="obList"
            type="ObservableList&lt;Object&gt;"/>

  

<TextView
            android:text='@{obList[Fields.FIRST_NAME]}'
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:text='@{String.valueOf(1 + (Integer)obList[Fields.AGE])}'
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

 *这里xml中Fields.FIRST_NAME & Fields.AGE会报错,这并不影响

最后绑定:

binding.obList = user.obList

 

 9.自动生成databinding变量:

layout中,xxxx.xml的名字会自动转换成xxxx类(databinding)

例如:

val binding = DataBindingUtil.inflate<RecyclerViewItemBinding>(
                LayoutInflater.from(parent?.context),
                R.layout.recycler_view_item,
                parent,
                false
        )

 RecyclerViewItemBinding就是根据recycler_view_item.xml生成的。

 

声明为Observable的变量都会自动生成在一个BR类中

 

10.Recycler View binding:

具体参考我的另一篇博文:http://jameskaron.iteye.com/admin/blogs/2411971

 

12.自定义Adapter:

 参考我的另一篇博文:http://jameskaron.iteye.com/admin/blogs/2412058

 

13.Custom Conversions:

例子:根据string来转换成color

<variable
            name="isColor"
            type="Boolean"/>

<TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="custom conversions"
            android:background="@{isColor? @string/gray:@string/blue}"
            />

 

public class TestViewModel {

    @BindingConversion
    public static ColorDrawable convertColorToDrawable(String colorString){
        int color = Color.parseColor(colorString);
        return new ColorDrawable(color);
    }
}

根据多次试验, @ BindingConversion不能使用kotlin,即使添加了@JVMStatic,仍会报not public static method的错误。

 

14.双向绑定:

<EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={user.firstname}"
            />

 这样,只要在UI修改了user.firstname的值,会实时双向传回到类中,所有调用user.firstname都会被更改了。

 

 

参考:

1.https://www.jianshu.com/p/5d6132e6dc14 

2.android developer:https://developer.android.com/topic/libraries/data-binding/index.htm

相关标签: databinding