• DataBinding 进阶用法


    DataBinding的进阶用法的演示:
    1、响应式user对象的演示
    2、list、recyclerView的演示使用
    3、kotlin中binding的写法的优势
    1. 布局文件
      1.1 activity_common_use.xml

    1. <layout xmlns:app="http://schemas.android.com/apk/res-auto"
    2. xmlns:tools="http://schemas.android.com/tools">
    3. <data>
    4. <variable
    5. name="user"
    6. type="org.hanyang.jetpack.binding.bean.CommonUser" />
    7. <variable
    8. name="fuser"
    9. type="org.hanyang.jetpack.binding.bean.FieldUser" />
    10. <variable
    11. name="ouser"
    12. type="org.hanyang.jetpack.binding.bean.ObUser" />
    13. <import type="android.view.View" />
    14. <variable
    15. name="show"
    16. type="Boolean" />
    17. <variable
    18. name="ladapter"
    19. type="org.hanyang.jetpack.binding.adapter.LAdapter" />
    20. <variable
    21. name="radapter"
    22. type="org.hanyang.jetpack.binding.adapter.RAdapter" />
    23. data>
    24. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    25. android:layout_width="match_parent"
    26. android:layout_height="match_parent"
    27. android:orientation="vertical"
    28. android:padding="10dp">
    29. <androidx.appcompat.widget.AppCompatTextView
    30. android:id="@+id/tv_common_user_info"
    31. android:layout_width="wrap_content"
    32. android:layout_height="wrap_content"
    33. android:gravity="center"
    34. android:text="@{user.name + user.age + user.sex + user.desc}"
    35. tools:text="普通user的数据信息" />
    36. <androidx.appcompat.widget.AppCompatButton
    37. android:id="@+id/btn_change_common"
    38. android:layout_width="wrap_content"
    39. android:layout_height="wrap_content"
    40. android:text="普通改变"
    41. android:textAllCaps="false" />
    42. <androidx.appcompat.widget.AppCompatTextView
    43. android:id="@+id/tv_field_user_info"
    44. android:layout_width="match_parent"
    45. android:layout_height="wrap_content"
    46. android:gravity="center"
    47. android:text="@{fuser.name+fuser.age+fuser.sex+fuser.desc}"
    48. android:textColor="@android:color/holo_blue_light"
    49. tools:text="Field的user的数据信息" />
    50. <androidx.appcompat.widget.AppCompatButton
    51. android:id="@+id/btn_change_field"
    52. android:layout_width="wrap_content"
    53. android:layout_height="wrap_content"
    54. android:text="改变Field"
    55. android:textAllCaps="false" />
    56. <androidx.appcompat.widget.AppCompatTextView
    57. android:id="@+id/tv_ob_user_info"
    58. android:layout_width="match_parent"
    59. android:layout_height="wrap_content"
    60. android:gravity="center"
    61. android:text="@{ouser.toString()}"
    62. android:textColor="@android:color/holo_green_dark"
    63. tools:text="Observable user的数据信息" />
    64. <androidx.appcompat.widget.AppCompatButton
    65. android:id="@+id/btn_change_ob"
    66. android:layout_width="wrap_content"
    67. android:layout_height="wrap_content"
    68. android:text="改变Observable"
    69. android:textAllCaps="false" />
    70. <androidx.appcompat.widget.AppCompatTextView
    71. android:layout_width="wrap_content"
    72. android:layout_height="wrap_content"
    73. android:text="这是一个显示/隐藏文案,根据checkbox的状态"
    74. android:visibility="@{show?View.VISIBLE:View.INVISIBLE}" />
    75. <androidx.appcompat.widget.AppCompatCheckBox
    76. android:id="@+id/cb_common"
    77. android:layout_width="wrap_content"
    78. android:layout_height="wrap_content"
    79. android:text="控制显示文案" />
    80. <include
    81. layout="@layout/layout_user"
    82. ouser="@{ouser}" />
    83. <LinearLayout
    84. android:layout_width="match_parent"
    85. android:layout_height="match_parent"
    86. android:orientation="horizontal">
    87. <ListView
    88. android:layout_width="0dp"
    89. android:layout_height="match_parent"
    90. android:layout_weight="1"
    91. app:adapter="@{ladapter}"
    92. tools:listitem="@layout/item_lv" />
    93. <androidx.recyclerview.widget.RecyclerView
    94. android:layout_width="0dp"
    95. android:layout_height="match_parent"
    96. android:layout_weight="1"
    97. app:adapter="@{radapter}"
    98. app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
    99. tools:listitem="@layout/item_lv" />
    100. LinearLayout>
    101. LinearLayout>
    102. layout>

      1.2 layout_user.xml

    1. <layout>
    2. <data>
    3. <variable
    4. name="ouser"
    5. type="org.hanyang.jetpack.binding.bean.ObUser" />
    6. data>
    7. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    8. android:layout_width="match_parent"
    9. android:layout_height="wrap_content"
    10. android:orientation="vertical">
    11. <androidx.appcompat.widget.AppCompatTextView
    12. android:layout_width="wrap_content"
    13. android:layout_height="wrap_content"
    14. android:text="@{ouser.toString()}" />
    15. LinearLayout>
    16. layout>

      1.3 item_lv.xml

    1. <layout xmlns:tools="http://schemas.android.com/tools">
    2. <data>
    3. <variable
    4. name="user"
    5. type="org.hanyang.jetpack.binding.bean.ObUser" />
    6. data>
    7. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    8. android:layout_width="match_parent"
    9. android:layout_height="wrap_content"
    10. android:layout_marginTop="1dp"
    11. android:orientation="horizontal"
    12. android:padding="5dp">
    13. <androidx.appcompat.widget.AppCompatTextView
    14. android:layout_width="30dp"
    15. android:layout_height="wrap_content"
    16. android:background="@android:color/holo_purple"
    17. android:gravity="center"
    18. android:text="@{user.name}"
    19. tools:text="姓名" />
    20. <androidx.appcompat.widget.AppCompatTextView
    21. android:layout_width="30dp"
    22. android:layout_height="wrap_content"
    23. android:background="@android:color/holo_orange_light"
    24. android:gravity="center"
    25. android:text="@{user.age+``}"
    26. tools:text="年龄" />
    27. <androidx.appcompat.widget.AppCompatTextView
    28. android:layout_width="30dp"
    29. android:layout_height="wrap_content"
    30. android:background="@android:color/holo_blue_dark"
    31. android:gravity="center"
    32. android:text="@{user.sex +``}"
    33. tools:text="性别" />
    34. <androidx.appcompat.widget.AppCompatTextView
    35. android:layout_width="0dp"
    36. android:layout_height="wrap_content"
    37. android:layout_weight="1"
    38. android:background="@android:color/holo_green_light"
    39. android:gravity="center"
    40. android:text="@{user.desc}"
    41. tools:text="简述" />
    42. LinearLayout>
    43. layout>

    2. 模型bean文件 User.kt

    1. /**
    2. * ----------------------------------------------------------------
    3. * 用于DataBinding的数据对象类,user,这里在kotlin中,多个public的class可以放在一个kt文件中
    4. */
    5. /**
    6. * 普通的数据类,这里用了kotlin的数据类 data class 也就是一个特殊的class而已。
    7. * val 表示不可变量,var 可变。这些在kotlin的代码演示中会有描述
    8. */
    9. data class CommonUser(
    10. val name: String, //姓名
    11. var age: Int, //年龄
    12. var sex: Int, //性别 0 女 1 男
    13. var desc: String //描述
    14. )
    15. /**
    16. * 这是部分属性可以databinding响应的user类,注意observable的属性需要public权限,否则dataBinding则无法通过反射处理数据响应
    17. */
    18. data class FieldUser(
    19. var name: String, //姓名
    20. var age: ObservableInt,//可响应的Int类型
    21. var sex: Int,
    22. var desc: ObservableField//可响应的String类型
    23. )
    24. /**
    25. * 继承dataBinding的baseObservable的user对象类
    26. * 这里是kotlin的写法,类似于java中,继承BaseObservable的对象类,
    27. * 需要响应变化的字段,就在对应变量的get函数上加 @Bindable 。然后set中notifyChange kotlin的写法,免去了java的getter setter的方式
    28. * 成员属性需要响应变化的,就在其set函数中,notify一下属性变化,那么set的时候,databinding就会感知到。
    29. */
    30. class ObUser() : BaseObservable() {
    31. //kotlin中类的构造函数可以多个,有主次之分,且次级构造函数必须调用主构造函数,如这里的this()
    32. constructor(name: String, age: Int, sex: Int, desc: String) : this() {
    33. this.name = name
    34. this.age = age
    35. // this.sex = sex
    36. this.desc = desc
    37. }
    38. //这是单独在set上@bindable,name可以声明private
    39. var name: String = ""
    40. //kotlin的成员属性必须初始化(或者lateinit)
    41. set(value) {
    42. //BR.name表示通知name这个属性的变化。 notifyChange() 通知所有变化
    43. notifyPropertyChanged(BR.name)
    44. field = value
    45. }
    46. @Bindable
    47. get() = field
    48. //这是在整个变量上声明@bindable,所以必须是public的
    49. @Bindable
    50. var age = 18
    51. set(value) {
    52. notifyPropertyChanged(BR.age)
    53. field = value
    54. }
    55. get() = field
    56. val sex = 1
    57. var desc: String = ""
    58. set(value) {
    59. field = "$value\n set中多余的拼接"//描述
    60. notifyPropertyChanged(BR.desc)
    61. }
    62. @Bindable
    63. get() = field
    64. override fun toString(): String {
    65. notifyChange()
    66. return "ObUser(name='$name', age=$age, sex=$sex, desc='$desc')"
    67. }
    68. }

    3. 适配器文件
      3.1 LAdapter.kt

    1. /**
    2. * ListView的adapter,简单演示,所以也不写viewHolder了
    3. */
    4. class LAdapter : BaseAdapter() {
    5. private var users: MutableList = arrayListOf()
    6. init {
    7. //初始化三个数据
    8. for (i in 0..2) {
    9. users.add(ObUser("小小$i", 20 + i, i % 2, "小小的说明 $i"))
    10. }
    11. }
    12. override fun getCount(): Int {
    13. return users.size
    14. }
    15. override fun getItem(position: Int): ObUser {
    16. return users[position]
    17. }
    18. override fun getItemId(position: Int): Long {
    19. return position.toLong()
    20. }
    21. //简单演示,就不用 viewHolder,实际请使用
    22. override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
    23. val inflater = LayoutInflater.from(parent?.context)
    24. var binding = ItemLvBinding.inflate(inflater)
    25. // Java 写法
    26. // if (convertView == null) {
    27. // binding = DataBindingUtil.inflate(inflater, R.layout.item_lv, parent, false)
    28. // } else {
    29. // binding = DataBindingUtil.getBinding(convertView)!!
    30. // }
    31. // binding.setVariable(BR.user, users.get(position))
    32. binding.user = users[position]
    33. return binding.root
    34. }
    35. }

      3.2 RAdapter.kt

    1. /**
    2. * 简单演示的RecyclerView的adapter
    3. */
    4. class RAdapter : Adapter<RAdapter.MyHolder>() {
    5. private var users: MutableList = arrayListOf()
    6. init {
    7. //初始化三个数据
    8. for (i in 0..2) {
    9. users.add(ObUser("小艾 $i", 20 + i, i % 2, "小艾的说明 $i"))
    10. }
    11. }
    12. override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
    13. val inflater = LayoutInflater.from(parent.context)
    14. val binding = ItemLvBinding.inflate(inflater)
    15. return MyHolder(binding)
    16. }
    17. override fun onBindViewHolder(holder: MyHolder, position: Int) {
    18. //java 写法可以setVariable
    19. holder.binding.user = users[position]
    20. holder.binding.executePendingBindings()
    21. }
    22. //kotlin,return的方式,可以简写
    23. override fun getItemCount() = users.size
    24. //在构造函数中声明binding变量,这样上面的holder才能引用到,如果不加val/var,就引用不到,就需要在class的{}内写get函数
    25. class MyHolder(val binding: ItemLvBinding) : ViewHolder(binding.root)
    26. }

    4. 测试页面 CommonUseActivity.kt

    1. /**
    2. * DataBinding的进阶用法的演示界面
    3. * 1、响应式user对象的演示
    4. * 2、list、recyclerView的演示使用
    5. * 3、kotlin中binding的写法的优势
    6. */
    7. class CommonUseActivity : AppCompatActivity(), View.OnClickListener {
    8. //一种懒加载的初始化控件的方式
    9. private val tvCommon: AppCompatTextView by lazy { findViewById(R.id.tv_common_user_info) }
    10. //这里由于使用了 apply plugin: 'org.jetbrains.kotlin.android.extensions' 会自动将xml中的id,关联为控件(也可以在代码中直接用tv_field_user_info)
    11. private val tvField: AppCompatTextView by lazy { tv_field_user_info }
    12. //这是稍后初始化的方式
    13. private lateinit var tvObservable: AppCompatTextView
    14. private lateinit var user: CommonUser //普通user对象
    15. private lateinit var fuser: FieldUser //部分属性可变的user
    16. private lateinit var obUser: ObUser //BaseObservable 的user
    17. override fun onCreate(savedInstanceState: Bundle?) {
    18. super.onCreate(savedInstanceState)
    19. //关联布局,binding 对象
    20. val binding = DataBindingUtil.setContentView(
    21. this,
    22. R.layout.activity_common_use
    23. )
    24. //初始化user,fuser,obuser的对象,并赋值到binding中去
    25. user = CommonUser("张三", 31, 1, "排行第三")
    26. binding.user = user
    27. //普通点类似java点方式,关联控件和注册事件
    28. binding.btnChangeCommon.setOnClickListener(this)
    29. //ObservableInt(
    30. fuser = FieldUser("李四", ObservableInt(20), 0, ObservableField("李四名字的由来"))
    31. //在代码中要获取desc这样的observable的属性,就需要用get(),而且get()的是可null的返回,
    32. //xml中直接用 user.desc即可,不需要写 .get(). 写了也无妨
    33. //fuser.desc.get()
    34. binding.fuser = fuser
    35. binding.btnChangeField.setOnClickListener(this)
    36. obUser = ObUser("王二", 22, 0, " 性别是改不了的,因为内部val声明了不可变量")
    37. binding.ouser = obUser
    38. //lateinit 延迟初始化
    39. tvObservable = tv_ob_user_info
    40. binding.btnChangeOb.setOnClickListener(this)
    41. //checkbox的响应
    42. cb_common.setOnCheckedChangeListener { compoundButton, checked ->
    43. //设置变量
    44. binding.show = checked
    45. }
    46. //adapter 设置
    47. binding.ladapter = LAdapter()
    48. binding.radapter = RAdapter()
    49. }
    50. //点击事件点处理
    51. override fun onClick(view: View?) {
    52. when (view?.id) {
    53. R.id.btn_change_common -> {
    54. user.age = 10; user.desc = "张三的改变desc,普通user对象不会影响binding"
    55. Toast.makeText(this, "注意上面的common user的info信息不会变化", Toast.LENGTH_SHORT).show()
    56. //当然,如果在此处,显示的代码设置Text,会变化,但是这不是数据绑定,因为你每次改变都要setText才生效
    57. //tvCommon.text = user.desc
    58. }
    59. R.id.btn_change_field -> {
    60. //fuser.name = "李四/李斯 "
    61. fuser.age.set(23)
    62. //值都会被改变
    63. fuser.desc.set("这两个field可以改变,你会发现名字的name是不会改变的")
    64. }
    65. R.id.btn_change_ob -> {
    66. obUser.name = "王二二"
    67. obUser.age = 222
    68. obUser.desc = "王二的名字,年龄,描述都会响应binding的变化"
    69. }
    70. }
    71. }
    72. }

    5. 效果图

     

  • 相关阅读:
    layui tree监控选中事件,同步选中和取消
    【网络原理】| 应用层协议与传输层协议 (UDP)
    mqtt使用方法
    手把手教你使用 Spring Boot 3 开发上线一个前后端分离的生产级系统(七) - Elasticsearch 8.2 集成与配置
    Qt编译出错ERROR: Unknown module(s) in QT: script
    Oracle EBS R12.1 FA 批量计划外折旧
    【第十三篇】- Maven 快照(SNAPSHOT)
    【AGC】增长服务1-远程配置示例
    Win10/11 删除文件资源管理器左侧栏目文件夹
    中文汉字转拼音首字母
  • 原文地址:https://blog.csdn.net/u011193452/article/details/126370670