Android DataBinding简单使用

1、配置

  • 在应用模块中的build.gradle文件中添加dataBinding元素,如下所示:
    在这里插入图片描述
android {
        ...
        dataBinding {
            enabled = true
        }
    }

2、布局绑定

  1. 在你想要编写dataBinding的视图xml文件根目录下按住alt+enter,如下所示:
    在这里插入图片描述
  2. 选中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中怎么使用吧。
  1. 新建一个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中使用的情况吧:
  1. 先引入RecyclerView依赖包:
implementation 'androidx.recyclerview:recyclerview:1.1.0'
  1. 编写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>

感兴趣的朋友可以自己跑一下代码试试哦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章