1、配置
- 在應用模塊中的build.gradle文件中添加dataBinding元素,如下所示:
android {
...
dataBinding {
enabled = true
}
}
2、佈局綁定
- 在你想要編寫dataBinding的視圖xml文件根目錄下按住alt+enter,如下所示:
- 選中Convert to data binding layout即可自動轉變成DataBinding的xml樣式:
<layout 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">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
我們先來簡單的看一下這個xml文件,以根標記layout開頭,裏面含有data元素和view根元素,生成DataBinding的xml文件以後,數據綁定庫會自動生成將佈局中的視圖和您數據綁定所需的類,名字爲xml文件名+DataBinding的駝峯命名。
注意:xml根目錄下不能有寬度高度屬性,否則會報如下錯誤:
3. 下面我們來簡單實現一下吧。
- 先編寫一個實體類
data class User(val firstName: String, val lastName: String)
- 再在xml文件中引用,type爲對應類的位置,name可以任意命名,但建議與實體類名一致,這樣好區別一些。
<data>
<variable
name="User"
type="com.yrf.databindingtest.User" />
</data>
...
- 接下來就是在view是視圖中引入數據,使用@{}語法,類名爲我們上面定義的name,代碼如下:
...
<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="@{User.firstName}" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{User.lastName}" />
</LinearLayout>
- 最後一步在我們的Activity中實現數據綁定,代碼如下:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// setContentView(R.layout.activity_main)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this,
R.layout.activity_main)
binding.user = User("張", "三")
}
代碼原始的setContentView刪掉,改用DataBindingUtil的setContentView方法,然後給相關屬性賦值即可,運行結果如下:
- 在Activiy中展現數據已經完成了,那麼在Fragment中如何使用呢,其實也很簡單,下面看一下在Fragment中怎麼使用吧。
- 新建一個Fragment文件,代碼如下:
class MyFragment: Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding: FragmentMainBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_main,
container, false)
binding.user = User("李", "四")
return binding.root
}
}
從代碼中我們可以看到,在Fragment中使用的是DataBindingUtil中的inflate方法,下面調用binding的getRoot方法返回View。
2.xml文件與Activity中的一模一樣,這裏就不展示了,由於這裏只是簡單的展示一下,我們直接在Activity中用fragment元素展示Fragment即可:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
...
<fragment
android:id="@+id/mainFragment"
android:name="com.yrf.databindingtest.MyFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
注意:fragment的id屬性不能漏,否則會報錯
- 接下來我們再來看一種在RecyclerView Adapter中使用的情況吧:
- 先引入RecyclerView依賴包:
implementation 'androidx.recyclerview:recyclerview:1.1.0'
- 編寫RecyclerView Adapter,代碼如下:
class MyRecyclerAdapter(private val userList: List<User>) :
RecyclerView.Adapter<MyRecyclerAdapter.ViewHolder>() {
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val binding: UserItemBinding = DataBindingUtil.bind(view)!!
fun bind(user: User) {
binding.user = user
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.user_item, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int = userList.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val user = userList[position]
holder.bind(user)
}
}
這裏和原生的寫法的區別就是綁定數據時有些差異,原生我們是先獲取相應的控件,然後調用控件的方法賦值,這裏我們是先綁定視圖,然後用binding賦值即可。xml文件與Activity和Fragment區別不大,就不做展示了。
其他地方寫法與原生無異,代碼如下:
val layoutManager = LinearLayoutManager(this)
layoutManager.orientation = LinearLayoutManager.VERTICAL
rlUserRecycler.layoutManager = layoutManager
val adapter = MyRecyclerAdapter(userList)
rlUserRecycler.adapter = adapter
最後運行結果如下:
完整代碼如下:
- MainActivity
class MainActivity : AppCompatActivity() {
private val userList = ArrayList<User>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(
this,
R.layout.activity_main
)
binding.user = User("張", "三")
userList.add(User("張", "三"))
userList.add(User("李", "四"))
userList.add(User("王", "五"))
val layoutManager = LinearLayoutManager(this)
layoutManager.orientation = LinearLayoutManager.VERTICAL
rlUserRecycler.layoutManager = layoutManager
val adapter = MyRecyclerAdapter(userList)
rlUserRecycler.adapter = adapter
}
}
- MyFragment
class MyFragment: Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding: FragmentMainBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_main,
container, false)
binding.user = User("李", "四")
return binding.root
}
}
- User
data class User(val firstName: String, val lastName: String)
- MyRecyclerAdapter
class MyRecyclerAdapter(private val userList: List<User>) :
RecyclerView.Adapter<MyRecyclerAdapter.ViewHolder>() {
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val binding: UserItemBinding = DataBindingUtil.bind(view)!!
fun bind(user: User) {
binding.user = user
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.user_item, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int = userList.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val user = userList[position]
holder.bind(user)
}
}
- activity_main
<layout 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">
<data>
<variable
name="User"
type="com.yrf.databindingtest.User" />
</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="@{User.firstName}" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{User.lastName}" />
<fragment
android:id="@+id/mainFragment"
android:name="com.yrf.databindingtest.MyFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rlUserRecycler"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</layout>
感興趣的朋友可以自己跑一下代碼試試哦~