Android JetPack系列---DataBinding

这一篇博客主要是针对DataBinding的使用以及入门

jetpack系列

第一篇:jetpack—Lifecycle的运用
第二篇:jetpack—ViewModel的了解
第三篇:jetpack—LiveData的使用
第四篇: JetPack系列—DataBinding的使用入门

首先了解DataBinding的作用主要是干什么?
DataBinding主要是用于数据绑定的一个库,借助该库,您可以使用声明性格式(而非程序化地)将布局中的界面组件绑定到应用中的数据源。

举个例子:
一般的写法我们的控件需要findviewbyid然后在对控件进行一个数据的设置。

val userNameTv: TextView = findViewById(R.id.userNameTv)
userNameTv.text = userdata.userName

databinding的写法 我们直接就在xml中绑定了数据

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

通过了上面的一个例子我们就应该很好的理解了布局中的界面组件绑定到应用中的数据源。

DataBinding的优势
1、原生支持MVVM框架
2、减少了Activity 的finviewbyid以及onClick等代码
3、相对于findviewbyid提高了应用的性能,并且有助于防止内存泄漏以及避免发生 Null 指针异常。更加安全
DataBinding的缺点
1、找问题的时候比较麻烦
2、在代码编写方面还没有索引,并且拥有的 IDE 支持也有限,对开发者而言不是太友好

具体的来说下databinding的实现方式。
一、编译环境
要先使用databinding,就要先将应用配置为使用数据绑定的模式,在项目的build.gradle, android{}结点中添开启databinding

android {
	......
	......
	 dataBinding {
        enabled = true
    }
}

这样我们就开启了数据绑定的模式
然后在xml中我们的数据绑定布局也有一些不一样的地方,梗节点用layout开头,后面更着data数据绑定标签,然后就是我们的布局元素


<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable
            name="userData"
            type="com.example.mymvvmproject.data.UserData" />
        <variable
            name="classesData"
            type="com.example.mymvvmproject.data.ClassesData" />
    data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{userData.userName}" />
 LinearLayout>
layout>

data中的userData变量描述了可以在布局中使用到这个数据UserData,UserData是我自己的一个实体类。

	<variable
            name="userData"
            type="com.example.mymvvmproject.data.UserData" />

然后下面的TextView绑定这个属性,这样这个textview就设置了userdata里面的userName这个字段

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

userdata实体类代码

data class UserData(
    val userName: String?,
    val nickName: String,
    val age: Int,
    val isShow: Boolean,
    @DrawableRes val userHead: Int
)

activity的代码绑定数据

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: ActivityMainBinding = DataBindingUtil.setContentView(
            this, R.layout.activity_main
        )
        val userdata = UserData("蘑菇", "洒家卖蘑菇", 1, true)
        val classesData = ClassesData("六年级", "3班", "王老师")
        binding.userData = userdata
        binding.classesData = classesData
    }
}

系统会为每个布局文件生成一个绑定类。默认情况下,类名称基于布局文件的名称,它会转换为 Pascal 大小写形式并在末尾添加 Binding 后缀。以上布局文件名为 activity_main.xml,因此生成的对应类为 ActivityMainBinding。

val binding: ActivityMainBinding = DataBindingUtil.setContentView(
            this, R.layout.activity_main
        )

数据绑定 有多少个实体就要绑定多少个,这个样子数据才能和界面关联起来,并且还有要与xml中variable中的name相对应。

binding.userData = userdata
binding.classesData = classesData

这个样子我们就简单的实现了一套databinding的模式。

接下来我们重点的说下xml里面的一些用法
1、简单的用法绑定一个字段,就是之前那样一摸一样的,布局中的表达式使用“@{...}”语法写入特性属性中。

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

2、设置默认的文字 用 default 来表示 可以应用string文件里面的文字

		<TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{userData.userName,default=@string/name}"/>

3、字符串判空 ?? 如果userName是null那么就使用nickName

		<TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
          		android:text="@{userData.userName ?? userData.nickName,default=@string/name}" />

4、设置int 这个地方需要转一下或者拼一个空的”“在后面,因为Textview本身也不支持直接设置int

		<TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{String.valueOf(userData.age)}" />

5、控件的显示和隐藏,值得注意的是这个地方我们需要引入View的包在开头的data里面,不然会找不到View这个对象,这个东西也说明了我们需要用到某些包的时候必须像这个样子引入。

 <data>
 		
        <import type="android.view.View" />
        <variable
            name="userData"
            type="com.example.mymvvmproject.data.UserData" />
    data>
		<TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:visibility="@{userData.show ? View.VISIBLE : View.GONE}" />   

6、字符串拼接 中间需要用+链接 其中字符串用单引号

		<TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{`洒家买蘑菇`+classesData.gradeLevel + classesData.classesName +classesData.teacherName}"
 />

7、引用textview中的内容,第二个textview引用第一个textview中的文字

	<TextView
            android:id="@+id/userNameTv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{userData.userName}"/>
	<TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{userNameTv.text}" />

8、应用静态类中的方法
静态类

object UserDataManger {
    fun setUserNumber(age: Int): String {
        return when (age) {
            1 -> {
                "哈哈哈哈哈"
            }
            2 -> {
                "呵呵呵呵呵"
            }
            3 -> {
                "嘻嘻嘻嘻嘻"
            }
            else -> {
                "呃呃呃呃呃"
            }
        }
    }
}

前提data中要导入包

<data>
        <import type="com.example.mymvvmproject.data.UserDataManger" />
        <variable
            name="userData"
            type="com.example.mymvvmproject.data.UserData" />
    data>
	<TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{UserDataManger.INSTANCE.setUserNumber(userData.age)}" />

9、list和map用法,导入包,本来的写法list但是<在xml中会报语法错误,所以必须转义List<String>

	<data>
		<import type="java.util.Map" />
		<import type="java.util.List" />

        <variable
            name="list"
            type="List<String>" />

        <variable
            name="map"
            type="Map<String, String>" />
    data>
	<TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{list[1]}" />

10、include标签的用法 需要注意的是 bind:userInfo="@{userData}"这个地方的userData是第一个页面variable 的name,userInfo是第二个页面variable 的name,必须对应上。
主页面


<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable
            name="userData"
            type="com.example.mymvvmproject.data.UserData" />
	data>
	<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
          <include
            layout="@layout/include_test_binding"
            bind:userInfo="@{userData}" />
	LinearLayout>
layout>

第二个页面


<layout>
    <data>
        <variable
            name="userInfo"
            type="com.example.mymvvmproject.data.UserData" />
    data>
    
    <LinearLayout
        android:orientation="vertical"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{userInfo.userName}" />

    LinearLayout>
layout>

11、点击事件
先写一个MainClickEvent 来接受点击事件

class MainClickEvent(val context: Context) {
    fun oneClick(view:View,string: String){
        view.isVisible = false
        Log.e("MainClickEvent","oneClick   $string")
    }
    fun twoClick(){
        Log.e("MainClickEvent","twoClick")
    }
}

然后xml绑定表达式可将视图的点击监听器分配给 oneClick() 方法 或者twoClick

	<data>
    <variable
            name="myClick"
            type="com.example.mymvvmproject.testDataBinding.MainClickEvent" />
    data>
		<TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="@{(theView)->myClick.oneClick(theView,userData.userName)}"
                android:text="@{userData.userName ?? userData.nickName,default=@string/name}" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="@{()->myClick.twoClick()}"/>

第三步MainActivity绑定 然后就可以实现我们的点击事件了

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: ActivityMainBinding = DataBindingUtil.setContentView(
            this, R.layout.activity_main
        )
        val userdata = UserData("哈哈哈哈", "洒家卖蘑菇", 1, true,R.mipmap.ic_launcher)
        binding.userData = userdata
        binding.myClick = MainClickEvent(this)
    }
}

databinding的基本的东西也就差不多就是这么多,有什么不对的地方也欢迎指正!

你可能感兴趣的:(JetPack全家桶,android,jetpack,databinding)