从这篇文章开始,就和大家一起来学习下 Android Jetpack 架构组件,这篇是系列篇一 Data Binding,下面就一起来学习下吧。
环境配置
很简单,只需要在app的build.gradle中设为启用即可。
android {
...
dataBinding {
enabled = true
}
}
Hello World
布局文件activity_main.xml代码如下, data里定义的绑定数据可以在activity中获取和赋值,布局中可以通过@{}
表达式来使用,layout下层最多只能包含一个data和一个View布局。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" >
<data>
<variable name="hello" type="String" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/helloTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{hello}"
android:textAllCaps="false"/>
</LinearLayout>
</layout>
MainActivity代码如下,这里Activity使用的是kotlin语言写的, 与java变化其实也不大,不太熟悉kotlin的朋友,可以慢慢熟悉一下。这里通过DataBindingUtil.setContentView
来设置contentView以及获取Binding对象,通过Binding对象就可以对布局文件里的data和view进行操作了。
package com.soaic.hellojetpack
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import com.soaic.hellojetpack.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var mBinding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
mBinding.hello = "Hello World!"
}
}
上面我们只需要对data里的hello属性赋值,因为helloTv的text绑定了hello, 所以text就能同步hello的值,以上就完成了一个Hello World例子!
布局binding获取绑定
通过DataBindingUtil对Activity设置ContentView并获取
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
通过layout自动生成的Binding类来获取实例
val binding: ActivityMainBinding = ActivityMainBinding.inflate(getLayoutInflater())
Fragment、ListView 或 RecycleView 适配器获取Binding实例
val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false)
// or
val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)
布局表达式
在表达式中可以使用以下运算符和关键字:
基本运算 + - / * %
字符串连接 +
逻辑 && ||
二进制 & | ^
一元 + - ! ~
转移 >> >>> <<
比较 == > < >= <=(注意<需要转义为<)
instanceof
分组 ()
文字 - 字符,字符串,数字, null
强转
方法调用
属性访问
数组访问 []
三元运算符 ?:
As Follows:
android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age > 13 ? View.GONE : View.VISIBLE}"
android:transitionName='@{"image_" + id}'
空指针合并操作符: (??) 如果左边不为null则选择左边,否则选择右边。
android:text="@{user.displayName ?? user.lastName}"
or
android:text="@{user.displayName != null ? user.displayName : user.lastName}"
数据类型
<data>
<import type="android.util.SparseArray"/>
<import type="java.util.Map"/>
<import type="java.util.List"/>
<variable name="list" type="List<String>"/>
<variable name="sparse" type="SparseArray<String>"/>
<variable name="map" type="Map<String, String>"/>
<variable name="index" type="int"/>
<variable name="key" type="String"/>
</data>
…
android:text="@{list[index]}"
…
android:text="@{sparse[index]}"
…
android:text="@{map[key]}"
资源表达式
android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"
android:text="@{@string/nameFormat(firstName, lastName)}"
对应string.xml
<string name="nameFormat">Full Name: %1$s:%2$s</string>
事件处理
添加事件MyHandlers类, 也可以直接用系统自带类,不需要创建,如android.view.View.OnClickListener
class MyHandlers