这一篇博客主要是针对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数据绑定标签,然后就是我们的布局元素
<?xml version="1.0" encoding="utf-8"?>
<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<String> 但是< 在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,必须对应上。 主页面
<?xml version="1.0" encoding="utf-8"?>
<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>
第二个页面
<?xml version="1.0" encoding="utf-8"?>
<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的基本的东西也就差不多就是这么多,有什么不对的地方也欢迎指正!
|