天天看点

【Jetpack系列】DataBinding简单使用(Kotlin)一、简单绑定二、响应事件 三、二级页面绑定四、自定义BindingAdapter五、双向绑定六、双向绑定结合LiveData 七、RecyclerView绑定

目录

一、简单绑定

1.配置gradle

2.更改布局文件

3.实例化布局文件

4.传递数据到布局文件

二、响应事件

1.新建事件响应类

2.布局添加

3.绑定数据

4.绑定响应方法 

 三、二级页面绑定

1.适用场景

2.绑定方法

(1)一级界面传递数据

(2)二级界面接收数据

四、自定义BindingAdapter

1.用途

2.使用

(1)配置gradle

(2)自定义BindingAdapter

(3)调用BindingAdapter

五、双向绑定

1.用途 

2.使用

(1)新建Model类

(2)新建ViewModel类

六、双向绑定结合LiveData

1.用LiveData包装数据类

2.改造ViewModel

 3.activity中观察LiveData

 七、RecyclerView绑定

1.创建item布局

2.创建Adapter

3.activity中加载数据

一、简单绑定

1.配置gradle

打开module层级的build.gradle文件,在android层级下添加如下代码

dataBinding{
        enabled = true
    }
           

2.更改布局文件

在布局文件中,光标移至最前面,按Alt+Enter,选择Convert to data binding layout,studio将自动更改为databinding布局

【Jetpack系列】DataBinding简单使用(Kotlin)一、简单绑定二、响应事件 三、二级页面绑定四、自定义BindingAdapter五、双向绑定六、双向绑定结合LiveData 七、RecyclerView绑定

【Jetpack系列】DataBinding简单使用(Kotlin)一、简单绑定二、响应事件 三、二级页面绑定四、自定义BindingAdapter五、双向绑定六、双向绑定结合LiveData 七、RecyclerView绑定

3.实例化布局文件

val binding: ActivityDataBindingBinding =
            DataBindingUtil.setContentView(this, R.layout.activity_data_binding)
           

4.传递数据到布局文件

布局文件中<data>节点下添加<variable>,用于数据绑定 

<data>
        <variable
            name="book"
            type="com.example.androidjetpack.DataBinding.Book" />
    </data>
           

activity中传递数据

binding.book = Book("title", "author", 5)
           

 在布局文件中绑定数据

<TextView
            android:text="@{book.title}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:text="@{book.author}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:text="@{book.rating}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
           

布局文件中引用静态类,在<data>节点添加引用

<import type="com.example.androidjetpack.databinding.BookRatingJavaUtil" />
           

 使用进入到静态类

<TextView
            android:text="@{BookRatingJavaUtil.getRating(book)}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
           

注:实际测试过程中,Kotlin的伴生对象静态方法在布局文件中引用会报错,后续将继续排查报错原因,故此处<import>的 BookRatingJavaUtil类为Java类

(原因已查明,参考https://blog.csdn.net/jie1123161402/article/details/81736677)

运行效果:

【Jetpack系列】DataBinding简单使用(Kotlin)一、简单绑定二、响应事件 三、二级页面绑定四、自定义BindingAdapter五、双向绑定六、双向绑定结合LiveData 七、RecyclerView绑定

二、响应事件

1.新建事件响应类

在activity中新建内部类,或独立成单独类文件

class EventHandleListener(var context:Context) {
    fun onClick(view: View) {
        Toast.makeText(context, "Clicked!", Toast.LENGTH_SHORT).show()
    }
}
           

2.布局添加<variable>

<variable
            name="EventHandler"
            type="com.example.androidjetpack.databinding.EventHandleListener" />
           

3.绑定数据

在activity中绑定数据

binding.eventHandler=EventHandleListener(this)
           

4.绑定响应方法 

在onclick中绑定响应方法

<Button
            android:textAllCaps="false"
            android:text="Click"
            android:onClick="@{EventHandler::onClick}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
           

运行效果

【Jetpack系列】DataBinding简单使用(Kotlin)一、简单绑定二、响应事件 三、二级页面绑定四、自定义BindingAdapter五、双向绑定六、双向绑定结合LiveData 七、RecyclerView绑定

 三、二级页面绑定

1.适用场景

使用于在布局文件中使用<include>标签引用页面时,将数据绑定到二级页面

2.绑定方法

(1)一级界面传递数据

布局变量book同时也是命名空间xmlns:app的一个属性,通过app:book传递数据

<include
            layout="@layout/layout_content"
            app:book="@{book}" />
           

(2)二级界面接收数据

新建layout_content.xml,使用variable接收绑定数据,在TextView中使用绑定数据

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

    <data>
        <variable
            name="book"
            type="com.example.androidjetpack.databinding.Book" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:gravity="center"
        android:layout_height="wrap_content" >

    <TextView
        android:text="@{book.title}"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_marginStart="16dp"
        android:text="@{book.author}"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    </LinearLayout>
</layout>
           
【Jetpack系列】DataBinding简单使用(Kotlin)一、简单绑定二、响应事件 三、二级页面绑定四、自定义BindingAdapter五、双向绑定六、双向绑定结合LiveData 七、RecyclerView绑定

四、自定义BindingAdapter

1.用途

为了让布局文件能承担更多的工作,处理更复杂的业务逻辑。

2.使用

(1)配置gradle

为了加载图片,引入Glide依赖

implementation 'com.github.bumptech.glide:glide:4.12.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
           

(2)自定义BindingAdapter

class ImageViewBindingAdapter {
    companion object{
        @BindingAdapter("image")
        @JvmStatic
        fun setImage(imageView: ImageView, imageUrl: String) {
            if (imageUrl.isNotEmpty()) {
                Glide.with(imageView)
                    .load(imageUrl)
                    .placeholder(R.mipmap.ic_launcher)
                    .error(R.mipmap.ic_launcher)
                    .into(imageView)
            } else {
                imageView.setBackgroundColor(Color.GRAY)
            }
        }
    }
}
           

(3)调用BindingAdapter

布局文件添加如下代码:

<variable
            name="networkImage"
            type="String" />
           
<ImageView
            app:image="@{networkImage}"
            android:layout_width="200dp"
            android:layout_height="100dp" />
           

activity添加如下代码: 

binding.networkImage="https://avatar.csdnimg.cn/0/F/2/1_u010444082.jpg"
           

运行效果: 

【Jetpack系列】DataBinding简单使用(Kotlin)一、简单绑定二、响应事件 三、二级页面绑定四、自定义BindingAdapter五、双向绑定六、双向绑定结合LiveData 七、RecyclerView绑定

五、双向绑定

1.用途 

简单绑定只能实现将数据绑定到视图上,双向绑定可以通过视图中控件的交互来直接改变数据,减少了在activity或viewModel中来对数据进行操作

2.使用

双向绑定与简单绑定类似,只不过在布局文件中,绑定的数据由原来的"@{}"变为"@={}",并在ViewModel中编写对应数据的get/set方法 

(1)新建Model类

class LoginModel(var userName:String)
           

(2)新建ViewModel类

viewModel中需要用ObservableField类来包装数据类,并且编写数据的set/get方法才能实现双向绑定

open class TwoWayBindingViewModel {

    private val loginModel = LoginModel("Keep Coding!")
    val observableField = ObservableField<LoginModel>()

    init {
        observableField.set(loginModel)
    }

    fun setUserName(userName: String) {
        observableField.get()!!.userName = userName
    }

    fun getUserName(): String {
        return observableField.get()!!.userName
    }
           

(3)在布局文件中进行双向绑定

<data>
        <variable
            name="viewModel"
            type="com.example.androidjetpack.databinding.two_way_binding.TwoWayBindingViewModel" />
    </data>
           
<EditText
            android:text="@={viewModel.userName}"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
           

(4)activity中传入viewModel

binding = DataBindingUtil.setContentView(this, R.layout.activity_two_way_binding)
        viewModel = TwoWayBindingViewModel()
        binding.viewModel = viewModel
           
fun getUserName(view: View) {
        binding.tv.text=viewModel.observableField.get()!!.userName
    }
           

运行效果:

【Jetpack系列】DataBinding简单使用(Kotlin)一、简单绑定二、响应事件 三、二级页面绑定四、自定义BindingAdapter五、双向绑定六、双向绑定结合LiveData 七、RecyclerView绑定

进入页面,EditText中显示userName的初始值“KeepCoding!”更改EditText中的值,点击按钮,发现viewModel中LoginModel数据类中的userName已被更改 ,并显示到下方TextView中

六、双向绑定结合LiveData

上一节中userName值的改变需要通过按钮重新获取才能显示更新,本节将改造上节代码,实现EditText中的值改变,TextView同步显示改变后的值

1.用LiveData包装数据类

class LoginModel(var userName:MutableLiveData<String>)
           

2.改造ViewModel

open class TwoWayBindingViewModel {

    private val loginModel = LoginModel(MutableLiveData("Keep Coding!"))
    val observableField = ObservableField<LoginModel>()

    init {
        observableField.set(loginModel)
    }

    fun setUserName(userName: String) {
        observableField.get()!!.userName.value = userName
    }

    fun getUserName(): String? {
        return observableField.get()!!.userName.value
    }
}
           

 3.activity中观察LiveData

viewModel.observableField.get()!!.userName.observe(this){
            binding.tv.text=it
        }
           

运行效果:

【Jetpack系列】DataBinding简单使用(Kotlin)一、简单绑定二、响应事件 三、二级页面绑定四、自定义BindingAdapter五、双向绑定六、双向绑定结合LiveData 七、RecyclerView绑定

此时改变EditText中的内容,TextView中的内容也同步改变  

 七、RecyclerView绑定

1.创建item布局

<?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>

        <import type="com.example.androidjetpack.databinding.BookRatingUtil" />

        <variable
            name="book"
            type="com.example.androidjetpack.databinding.Book" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal"
        android:padding="8dp">

        <ImageView
            android:layout_width="48dp"
            android:layout_height="48dp"
            app:image="@{book.imageUrl}" />

        <LinearLayout
            android:layout_marginStart="16dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{book.title}" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{book.author}" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{BookRatingUtil.getRatingString(book)}" />
        </LinearLayout>

    </LinearLayout>
</layout>
           

2.创建Adapter

class BookAdapter(var books: List<Book>) : RecyclerView.Adapter<BookAdapter.BookViewHolder>() {

    lateinit var binding: ItemBookBinding

    class BookViewHolder(binding: ItemBookBinding) : RecyclerView.ViewHolder(binding.root)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookViewHolder {
        binding = DataBindingUtil.inflate(
            LayoutInflater.from(parent.context),
            R.layout.item_book,
            parent,
            false
        )
        return BookViewHolder(binding)
    }

    override fun onBindViewHolder(holder: BookViewHolder, position: Int) {
        binding.book = books[position]
    }

    override fun getItemCount(): Int {
        return books.size
    }
}
           

3.activity中加载数据

binding = DataBindingUtil.setContentView(this, R.layout.activity_recycler_view_binding)
        val list = ArrayList<Book>()
        for (i in 0..100) {
            val book = Book("Jetpack", "Keep Coding!", i % 6)
            book.imageUrl = "https://avatar.csdnimg.cn/0/F/2/1_u010444082.jpg"
            list.add(book)
        }
        binding.rv.layoutManager = LinearLayoutManager(this)
        binding.rv.adapter = BookAdapter(list)
           

运行效果:

【Jetpack系列】DataBinding简单使用(Kotlin)一、简单绑定二、响应事件 三、二级页面绑定四、自定义BindingAdapter五、双向绑定六、双向绑定结合LiveData 七、RecyclerView绑定

源码已上传Gtihub

https://github.com/ZYALLZ/AndroidJetpack