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>

感興趣的朋友可以自己跑一下代碼試試哦~

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