Kotlin + Databinding的使用及注意点

一、在模块app中的build.gradle中配置:

1.apply plugin: ‘kotlin-kapt’//kapt 插件

2.//开启dataBinding

android {   

dataBinding {
        enabled = true

    }

}

dependencies {
implementation”org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version”
“com.android.databinding:compiler:$gradle_version”
}

注意:

kapt “com.android.databinding:compiler:$gradle_version” 如果AndroidStudio是3.2以上版本,就不用使用kapt,直接”com.android.databinding:compiler:$gradle_version” ,不然编译时会报异常:[kapt] An exception occurred: java.lang.NullPointerException 这是因为:Android studio 3.2.0-beta01开始,数据绑定不再需要在gradle文件中声明其注释处理器依赖项,因为数据绑定能够解析其依赖性。

二、验证Databinding的配置

1.我们修改布局文件:activity_main.xml,布局文件这里一定要改成layout开始的才行:

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="hello kotlin"/>
    </LinearLayout>
</layout>

2.然后我们来看下MainActivity:

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
}
}

注意:setContentView<ActivityMainBinding>中的ActivityMainBinding是对应xml布局文件的,如:R.laiyout.activity_main,这里如果没有配置和Databinging会提示找不到 ActivityMainBinding,也就是如果配置好Databinging,项目会自动生成ActivityMainBinding文件


三、Databinding的使用

1.我们先建一个数据实体类:

package com.hugecore.mojidict

class Person(val name: String, val sex: String){}

2.在布局文件中使用数据:

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

    <data>
        <variable
            name="person"
            type="com.hugecore.mojidict.Person" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="@{person.name}"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="@{person.sex}"/>
    </LinearLayout>
</layout>

3.在activity中使用:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val dataBinding = DataBindingUtil.setContentView<ActivityMainBinding>(this,R.layout.activity_main)
        dataBinding.person = Person("kotlin","women")

    }
}

4、在RecycleView中的使用

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    val context = parent.context
    val itemNews = DataBindingUtil.inflate<ItemNewsListVmBinding>(LayoutInflater.from(context),
                R.layout.item_news_list_vm,
                parent,
                false)
    return ArticleChoicenessViewHolder(itemNews.root)
   
}

5、RecycleView+DataBinding 数据刷新时屏幕闪一下的问题解决办法如下

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {

    val articleBinding = DataBindingUtil.getBinding<ItemNewsListVmBinding>(holder.itemView)
    articleBinding?.executePendingBindings()

}

6、adapter中Imageview的用法如下

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

    <data>
        <variable
            name="article"
            type="com.hugecore.mojidict.core.model.Article" />
    </data>

          <com.makeramen.roundedimageview.RoundedImageView
                android:id="@+id/icon"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_centerVertical="true"
                android:scaleType="center"
                articleCoverImgUrl="@{article.coverId}"
                app:riv_corner_radius="10dp"
                app:riv_border_color="#FFFFFF"/>
</layout>

@BindingAdapter(value = ["articleCoverImgUrl"])
@JvmStatic
fun articleCoverImg(view: ImageView, identity: String) {
    view.loadImage(view.context, view, ImageType.ARTICLE_ALBUM, identity, null)
}