jetpack之数据绑定, DataBinding(一)简单形式

在这里,实现android 的数据绑定,是依靠Data Binding library库实现的。目的是将数据的交互由activity移动到layout布局文件和专门的数据类中,从而做到更好的封装。初学jetpack包,其实是抱着偷懒的心理来的。一开始感觉,这个databing 与 srping boot 当中mybbits很是想像,解决的问题也是数据展示与数据处理分离。想让布局的数据随着数据对象的变化自动变化。

现在就文档上介绍的三种方法来交流下个人在使用的心得。其实这三种数据绑定方法,分别是由浅入深的,数据类型从刚开始的初始类型,到可观察的初始类型,再可观察的初始类型及其容器,最后是整个可观察的类,实现自行更新ui,数据逻辑。开始走起!

一、最简单形式

layout —— 数据类  —— activity



   
       
   
   
       
       
   

其中表达式是@{}, 数据是在data标签内,并表明了数据variable变量的名字,你可以下方面的控件中引用对象的名字,类型,你定义的数据类。在data标签里还可以import,导入资源,像这样。


        
        

这样,你声明的variable,和import来的资源,软件包,都可以在下面的布局控件中在@{}表达中使用,还有它也有一个default可以让你指定默认值, 这个要用``包住,数字键1前面的那个键。表示是个常量。

数据类:

public class User {
  public final String firstName;
  public final String lastName;
  public User(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
  }
}

final修饰符表示,这个类型数据,程序只能用读,数据不变的。

activity这样的在onCreate方法中:

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
   User user = new User("Test", "User");
   binding.setUser(user);
}

ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());

是从运行是获那个绑定对象。ActivityMainBinding 这是一个根据layout文件名称生成的生成类,以Binding为后缀。

这三者里面,在layout文件中要使用的表达式,很强大,支持下下运算,见识下:

一类跟java代码中相似的运算符:

Mathematical + - / * %
String concatenation +
Logical && ||
Binary & | ^
Unary + - ! ~
Shift >> >>> <<
Comparison == > < >= <= (Note that < needs to be escaped as <)
instanceof
Grouping ()
Literals - character, String, numeric, null
Cast
Method calls
Field access
Array access []
Ternary operator ?:

而不能使用类似java中的this, supper, new, 或直接代码调用。

支持??空联合运算 ,可以看作?:的缩写,不为空选择前面,空时选择后面值。

android:text="@{user.displayName ?? user.lastName}"

还支持,对象属性引用,只是注意空指针引用,那会引发异常。

android:text="@{user.lastName}"

更支持,集合运算[]


    
    
    
    
    
    
    
    

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

map[key]当然也可以用map.key来代替。

注意,如果双引号要用字符串字面量,则要用键盘数字1前面那个符号,叫后引号。又或者字面量用双引号,而外层用单引号。

表达内,还可以引用资源:

android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"

支持还支持string.xml里面格式化字符串,像这样

Hello, %1$s! You have %2$d new messages.

你需要传参数:

android:text="@{@string/welcome_messages(firstName, 50)}"

还少用的字符串复数形式:

 
        
        %d song found.
        %d songs found.
    

也记要传参.

还有一些资源引用时,表达式内要明确求值格式,这些是:

某些资源引用需要明确求值的表达格式
Type Normal reference Expression reference
String[] @array @stringArray
int[] @array @intArray
TypedArray @array @typedArray
Animator @animator @animator
StateListAnimator @animator @stateListAnimator
color int @color @color
ColorStateList @color @colorStateList
     
     
     
     
     
     
     
     

以是在表示式里求值,赋给控件属性,控件的属性中除了值,还有一种是事件处理器。当控件的事件被触发后,要调用相应的处理代码,这个我们提供并设定。databing 库为我们提供了两方法来实现,方法引用和事件绑定。

一是通过方法引用。我们不仅可以将数据对象绑定到layout当中,还可以将一个用于处理事件的类,也放到layout的data标签中去。然后在控件的响应事件处引用我们处理事件类中的方法。比如:



   
       
       
   
   
       
   

许多控件都onClick,控件的事件也会传递,注意引起冲突的地方。其中一些特别的如:

 

Class Listener setter Attribute  
ZoomControls setOnZoomInClickListener(View.OnClickListener) android:onZoomIn  
ZoomControls setOnZoomOutClickListener(View.OnClickListener) android:onZoomOut  
       
SearchView setOnSearchClickListener(View.OnClickListener) android:onSearchClick  
       
       
       

第二方法,处理方法,绑定事件侦听器。如示:



    
        
        
    
    
        

需要我们定义那个侦听器:

public class Presenter {
    public void onSaveClick(Task task){}
}

当表达中有了这么一个回调监听器的指定,数据绑定模块会自动产生侦听器实例,并把它注册到事件流当中来。这里侦听器,可以给它传参,也可以不传,还可以确定返回值。不过,值得注意的是避免空值。

如果你需要一个带指示的表达式,可以这样:

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

尽管表达式地很强大,但不要滥用,使用代码阅读困难,应该很简单,只像是从ui到从到你的回调,你应该实现回调代码内的业务逻辑,以便表达内用到它实现相应的功能。

最后,再补充下import 和 include,它们有效地扩展了数据的能力范围。

import有点像代码的中导入到当前空间一样,只是为了避免名字冲突你还可以使用别名,如:


除了导入系统的类,也可以是自己的类,并可以作为引用数据的数据类型,如:


    
    
    
    

引入地类可以作为强型转换,也可有表达式内引用它的静态成员。作为管理代码的一部分,java.lang.*是自动导入的。

在data标签中的变量variable可以有多个条目,要标明name,type,如:


    
    
    
    

注意此处类型会编译时侦测,类型是实现了Observable或Observable collection的类型,还要注意不同的layout配置文件相同变量名合并时冲突问题,都是要避免的。根据layout文件自动生成的绑定类,对变量有一对setter,getter有其缺省值,引用型为null,int为0, boolean为false等,但一个很特别的变量名,context,它是从根View的getContext()方法中得到Context对象,它会覆盖你明确定义的context.

接下来是include,将别处layout引用变量的表达式,引入到当前声明变量的layout当中。如:



   
       
   
   
       
       
   

不支持merge:



   
       
   
   
       
       
   

总结:这里首先是介绍了简单数据绑定,重点是表达使用,引入,导入。特点是表达式内容较大。

你可能感兴趣的:(android)