Android DataBinding简单使用
程序员文章站
2022-05-14 15:47:39
...
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>
感兴趣的朋友可以自己跑一下代码试试哦~