- ViewBinding:简单来说,代替findViewById,更大的优点是空安全。
- DataBinding:MVVM好伙伴
一、ViewBinding
官方文档:developer.android.google.cn/topic/libra…
ViewBinding是区分Android studio版本的。可以分为4.0之前和之后
// 3.6,4.0之前
android {
...
viewBinding {
enabled = true
}
}
// Android Studio 4.0之后
android {
...
buildFeatures {
viewBinding = true
}
}
View Binding是Android Studio 3.6推出的新特性,目的是为了替代findViewById(内部实现还是使用findViewById)
优点
-
Null 安全:由于视图绑定会创建对视图的直接引用,因此不存在因视图 ID 无效而引发 Null 指针异常的风险。此外,如果视图仅出现在布局的某些配置中,则绑定类中包含其引用的字段会使用
@Nullable标记。 -
类型安全:每个绑定类中的字段均具有与它们在 XML 文件中引用的视图相匹配的类型。这意味着不存在发生类转换异常的风险。
简单使用
android {
...
buildFeatures {
viewBinding = true
}
}
class MainActivity : AppCompatActivity() {
private lateinit var mainBinding:ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 调用生成的绑定类中包含的静态 inflate() 方法
mainBinding = ActivityMainBinding.inflate(layoutInflater)
mainBinding.tvName.text= "张三丰长大了"
// 当然了,依然可以 findViewById,只是一般没必要了
// mainBinding.root.findViewById<>()
mainBinding.tvAge.text = "20"
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
>
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="小张三丰"
/>
<TextView
android:id="@+id/tv_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="18岁"
android:layout_marginTop="10dp"
/>
<TextView
android:id="@+id/tv_diary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="日记本"
android:layout_marginTop="10dp"
/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
个别页面不想用 viewBinding
如果想在生成绑定类时忽略某个布局文件,将 tools:viewBindingIgnore="true" 属性添加到相应布局文件的根视图中,即可。
DataBinding
开启DataBinding是区分Android studio版本的。可以分为4.0之前和之后
// 4.0之前
android {
...
dataBinding {
enabled = true
}
}
// Android Studio 4.0之后
android {
...
buildFeatures {
dataBinding = true
}
}
二、DataBinding
说到DataBingding,就避免不开MVVM。(M 是指 Model,V 是指 View,VM 是指ViewModel)
优点
- 替换 findViewById ,减少模板代码
- 解决类型安全问题
- 解决空安全问题
- 保证了数据的一致性
如何使用
- 1、
开启 dataBinding = true - 2、
xml根布局必须是以 layout 开始 - 3、
根布局 layout下需要有个 data 标签(data 标签用于声明要用到的变量以及变量类型,要实现 MVVM 的 ViewModel 就需要把数据(Model)与 UI(View)进行绑定,data 标签的作用就像一个桥梁搭建了 View 和 Model 之间的通道)
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewmodel"
type="com.myapp.data.ViewModel" />
</data>
<ConstraintLayout... /> <!-- UI layout's root element -->
</layout>
小技巧:生成layout
在布局文件,按下option+回车(alt+回车),即可快速在最外层的layout。(注意一定是开启了 dataBinding = true 的前提下 )
并且还会生成data标签。
从最简单的的使用说起
buildFeatures {
dataBinding = true
}
.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mainBinding =
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
var info = UserInfo()
info.name = "南极企鹅"
info.hobby = "打阿豆"
mainBinding.userInfoBean = info
}
}
.
<?xml version="1.0" encoding="utf-8"?>
<!--根布局必须是layout-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 绑定数据-->
<data>
<variable
name="userInfoBean"
type="com.am.databindingtest.UserInfo" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
>
<TextView
android:id="@+id/tv_name"
android:text="@{userInfoBean.name}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="用户名"
/>
<TextView
android:id="@+id/tv_hobby"
android:text="@{userInfoBean.hobby}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="爱好"
android:layout_marginTop="10dp"
/>
</LinearLayout>
</layout>
运行:
.
关于xml里的data标签,还有其他的使用方法
data 之 import 方式
<?xml version="1.0" encoding="utf-8"?>
<!--根布局必须是layout-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 绑定数据-->
<data>
<!-- import 进来,这样就不用每次都指明整个包名路径了-->
<import type="com.am.databindingtest.UserInfo"/>
<variable
name="userInfoBean"
type="UserInfo" />
</data>
我们写的类需要全路径引入,但是如果是String之类,就可以直接使用,因为java.lang.* 包中的类会被自动导入,所以可以直接使用
data 之 alias 别名
如果存在 import 的类名相同的情况,可以使用 alias 指定别名
<data>
<import type="com.am.databindingtest.UserInfo" />
<import
alias="TempUser"
type="com.am.databindingtest.xxxxx.UserInfo" />
<variable
name="userInfo"
type="User" />
<variable
name="tempUserInfo"
type="TempUser" />
</data>
其他
通过Model改变视图,这是单向绑定,如果通过视图可以改变Model的值,那么就是双向绑定。
{}里面可以包含很多的表达式
databinding可以绑定事件
其他的懒得写了,看下其他文章吧 cloud.tencent.com/developer/a…