Android Jetpack之Databinding问题反馈

使用 dataBinding 需要在 app module 下面的 build.gradle 文件中进行配置,具体如下:

android {
...
    //设置支持dataBinding   
    dataBinding {
        enabled = true
    }
...

}

其他简单的细节就不讲了,网上资料很多,这里主要记录一下平时在开发中遇到过的不好解决或者是借助搜索引擎才解决掉的问题。

1、可以在设置属性值的时候,设置默认值

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="bean" type="com.example.NaviBean"/>
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <!--dataBinding中具体属性值的配置在"@{}"中进行配置-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{bean.name,default=姓名}"/>
    </LinearLayout>
</layout>

2、特殊表达式

  • 三目运算符简化
    //完整写法android:text="@{user.displayName != null ? user.displayName : user.lastName}"
    //简写android:text="@{user.displayName ?? user.lastName}"

     

  • 空指针异常处理

    生成的绑定类会自动检查 null 值以避免 NullPointerException,在表达式 @ {user.name} 中,如果 user 为 null,则为user.name 分配其默认值 null。 如果引用 user.age,其中 age 的类型为 int,则数据绑定使用默认值0。

集合

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <import type="java.util.Map" />
        <import type="java.util.List" />        <!--Map-->        
        <variable
            name="map"
            type="Map&lt;String,String>" />        
        <variable
            name="key"
            type="String" />        <!--List-->        
        <variable
            name="list"
            type="List&lt;String>" />        
        <variable
            name="index"
            type="int" />    
    </data>
        <!--注意Map和List取值方式-->    

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">        

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{map.key}" />        

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{list[0]}" />    
    </LinearLayout>
</layout>

对于 Map 类型的数据可以在表达式 @{} 中使用 map.key 来获取 Map 集合中 key 对应的 value 值,List 类型的数据直接使用索引来取值,此外在 variable 标签中使用到的 < 要进行转义,及使用 < 来代替 <,否则报错如下:

> Error: 与元素类型 "variable" 相关联的 "type" 属性值不能包含 '<' 字符。
  • @{} 表达式中使用字符串

       如何在 @{} 表达式中使用字符串而不是字符串变量呢,有两种方式,具体如下:

<!--使用单引号-->
<TextView    
            android:layout_width="wrap_content"    
            android:layout_height="wrap_content"    
            android:text='@{map["key"]}' />
<!--使用后引号-->
<TextView    
            android:layout_width="wrap_content"    
            android:layout_height="wrap_content"    
            android:text="@{map[`key`]}" />
<TextView         
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{`hhhhh `+bean.name+` sss `}" />
<!--在@{}中可以使用字符串资源-->
<TextView        
            android:layout_width="wrap_content"        
            android:layout_height="wrap_content"        
            android:text="@{@string/app_name}"/>

在 xml 中调用事件方法时,可以在配置当前 View,具体如下:

<Button    
            android:layout_width="match_parent"    
            android:layout_height="wrap_content"    
            android:onClick="@{(view) -> presenter.onClickEvent(user)}"    
            android:text="click me 3" />
public class MyPresenter {    
    public void onClickEvent(View view, User user){}
}

此外,也可以在事件绑定时使用三目运算符,此时可将 void 作为操作符使用,使用方式参考如下:

android:onClick="@{(v) -> v.isVisible() ? presenter.doSomething() : void}"

3、自定义绑定类

从前面可知,默认状态下绑定类名称是由布局文件名称决定,那么如何自定义绑定类呢,在布局文件 data 标签上使用 class 属性指定自定义的绑定类名即可,当然也可以在自定义类名前面添加完成的包路径,参考如下:

<!--自定义绑定类-->
<data 
        class="com.manu.test.CustomBinding">    
        <variable name="user" type="com.manu.databindsample.data.User"/>
</data>

在 databinding 中使用 import 关键字导入相关的类,java.lang.* 下面的相关类默认自动导入,如果有相同名字的 View 可以使用使用 alias 来区分,参考如下:

<import type="android.view.View"/>
<import type="com.manu.View"  alias="MView"/>

4、include包含布局

使用 variable 关键字定义要在 xml 布局中使用的变量,如果使用了 include 布局,则要使用 bind 绑定 include 包含的布局与主布局使用同样的变量,创建一个 include 包含的布局 test_layout.xml 文件,具体如下:

<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android">    
<data>        
    <variable  name="userTest"            
    type="com.manu.databindsample.data.User" />    
</data>    
<LinearLayout        
     android:layout_width="match_parent"       
     android:layout_height="match_parent">        
    <TextView            
        android:layout_width="wrap_content"            
        android:layout_height="wrap_content"            
        android:text="@{`this is include content...`+userTest.getName(),default=user}" />    
 </LinearLayout>
</layout>

 

然后,在主布局中引用这个布局,具体如下:

<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android"    
        xmlns:bind="http://schemas.android.com/apk/resauto">    
<data>        
    <variable  
        name="user"            
        type="com.manu.databindsample.data.User" />    
</data>    
<LinearLayout        
    android:layout_width="match_parent"        
    android:layout_height="match_parent">         
    <!--bind绑定变量-->        
    <include            
        layout="@layout/test_layout"            
        bind:userTest="@{user}" />    
    </LinearLayout>
</layout>

这样通过 bind 就绑定了两个布局中使用到的 User 类型的变量,使得两个布局中使用的变量是同一个变量,此外,databinding 不支持 merge 标签。

 

5、xml中包含&&符号

& ——> &amp;

代码里:

!TextUtil.isEmpty(viewCtrl.phone) && viewCtrl.phone.length() == 11 

xml:

@{!TextUtil.isEmpty(viewCtrl.phone) &amp;&amp; viewCtrl.phone.length() == 11 }

 

 

文章转载自Android Jetpack组件之DataBinding详解,如果侵权,告之立删!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值