dataBinding数据绑定(一)

编译环境

要将应用配置为使用数据绑定,请在应用模块的build.gradle文件中添加dataBinding元素:

android {
        ...
        dataBinding {
            enabled = true
        }
    }
    

使用数据绑定库

数据绑定的布局文件以根标记layout开头,后跟data元素和view根元素:




    
        
    

    

        

    


data中使用了包名为com.jetpackdemoUser文件,并为此对象设置了name:user
TextView中:android:text="@{user.name}"表示为TextView设置username属性值。
完成布局文件后,系统会为每一个布局文件生成一个绑定类,默认情况下,类名基于布局文件的名称,将xml文件的名称转换为驼峰大小写,并在末尾添加Binding一词。

lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.user = User("hello")
    }

如果在FragmentListViewRecyclerView适配器中使用数据绑定,则可以使用DataBindingUtilinflate方法:

val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)

布局表达式

可以在布局文件的使用一下运算符和关键字:

  • 算术运算符+ - * / %
  • 字符串连接运算符 +
  • 逻辑运算符 && ||
  • 二元运算符 & | ^
  • 一元运算符 + - ! ~
  • 移位运算符 >> >>> <<
  • 比较运算符 == > < >= <=(<需要转义为<)
  • instanceof
  • 分组运算符 ()
  • 字面量运算符-字符、字符串、数字、null
  • 类型转换
  • 方法调用
  • 字段访问
  • 数组访问[ ]
  • 三元运算符 ?:
缺少的布局表达式
  • this
  • super
  • new
  • 显式泛型调用
Null合并运算符
android:text="@{user.name ?? user.sex}"

如果左边运算不为null则选择左边运算,否则选择右边运算。

属性引用
android:text="@{user.name}"
避免出现Null指针异常

生成的数据绑定代码会自动检查有没有null值并避免出现null指针异常。如果在表达式中Stringnull则分配默认值null

集合表达式

为了方便访问,可使用[ ]运算符访问常见集合,例如数组、列表、稀疏列表和映射。


         
         
         
         
         
         
          

...
android:text="@{list[index]}"
...
android:text="@{sparse[index]}"
...
android:text="@{map[key]}"

在集合中,必须使用转义<字符。例如:不要写成List形式,而是必须写成List<String>

获取map中的值
android:text='@{map.get("name")}'

事件处理

通过数据绑定,您可以编写从视图分派的表达式处理事件(例如:onClick()方法)。事件名称由监听器方法的名称确定。
可以使用以下机制处理事件:

方法引用:在表达式中,您可以引用符合监听器方法签名的方法,当表达式求值结果为方法引用时,数据绑定会将方法引用和所有者对象封装到监听器中,并在目标视图上设置该监听器。如果表达式的求值结果为 null,则数据绑定不会创建监听器,而是设置null监听器。
监听器绑定:这些是在事件发生时进行求值的lambda表达式。数据绑定始终会创建一个要在视图上设置的监听器。事件被分派后,监听器会对lambda表达式进行求值。

方法引用

一个主要优点是表达式在编译时进行处理,因此,如果该方法不存在或其签名不正确,则会收到编译时错误。

    class MyHandlers {
        fun onClickFriend(view: View) { ... }
    }

    
       
           
           
       
       
           
       
    

方法引用中的签名必须和方法中的签名保持一致,并且参数也保持一致,不能自定义参数。

监听器绑定

监听器绑定是在事件发生时运行的绑定表达式。它们类似于方法引用,但允许您运行任意数据绑定表达式。此功能适用于 Gradle 2.0 版及更高版本的 Android Gradle 插件。
在方法引用中,方法的参数必须与事件监听器的参数匹配。在监听器绑定中,只有您的返回值必须与监听器的预期返回值相匹配(预期返回值无效除外)。

    class Presenter {
        fun onSaveClick(task: Task){}
    }

然后,您可以将点击事件绑定到 onSaveClick() 方法


    
        
            
            
        
        
               

如果监听的事件返回类型不是void的值,那么表达式也必须返回相同类型的值(比如长按事件返回值是boolean)。

fun onSaveClick(task: Task): Boolean{}

从以上说明可以看出,方法引用更适合简单的事件处理,并且方法不需要自定义参数。监听器则更适合复杂的事件处理,方法可以自定义参数。

避免使用复杂的监听器

监听器表达式功能非常强大,可以使您的代码非常易于阅读。另一方面,包含复杂表达式的监听器会使您的布局难以阅读和维护。这些表达式应该像将可用数据从界面传递到回调方法一样简单。您应该在从监听器表达式调用的回调方法中实现任何业务逻辑。

导入、变量和包含

导入

通过导入功能,您可以轻松地在布局文件中引用类,就像在托管代码中一样。您可以在 data 元素使用多个 import 元素,也可以不使用。以下代码示例将View类导入到布局文件中:


        
    

上述方法中导入了View类,可以引用View的属性,比如设置显示:

android:visibility="@{user.man? View.VISIBLE : View.GONE}"
类型别名

当类名有冲突时,其中一个类可使用别名重命名。以下示例将com.example.real.estate软件包中的View类重命名为Vista


    
导入其他类

        
        
        
        
    

还可以通过使用导入的类型来对表达式的一部分进行类型转换。以下示例将connection属性强制转换为类型User


在表达式中引用静态字段和方法时,也可以使用导入的类型。以下代码会导入MyStringUtils类,并引用其 capitalize方法:


        
        
    
包含

通过使用应用命名空间和特性中的变量名称,变量可以从包含的布局传递到被包含布局的绑定。以下示例展示了来自 name.xml 和 contact.xml 布局文件的被包含 user 变量:


    
       
           
       
       
           
           
       
    

数据绑定不支持 include 作为 merge 元素的直接子元素。例如,以下布局不受支持:


    
       
           
       
       
           
           
       
    

你可能感兴趣的:(dataBinding数据绑定(一))