欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android DataBinding简单使用

程序员文章站 2022-05-14 15:47:39
...

1、配置

  • 在应用模块中的build.gradle文件中添加dataBinding元素,如下所示:
    Android DataBinding简单使用
android {
        ...
        dataBinding {
            enabled = true
        }
    }

2、布局绑定

  1. 在你想要编写dataBinding的视图xml文件根目录下按住alt+enter,如下所示:
    Android DataBinding简单使用
  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根目录下不能有宽度高度属性,否则会报如下错误:
Android DataBinding简单使用
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方法,然后给相关属性赋值即可,运行结果如下:
Android DataBinding简单使用

  • 在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

最后运行结果如下:
Android DataBinding简单使用
完整代码如下:

  • 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>

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