美文网首页
DataBinding学习(下)

DataBinding学习(下)

作者: 慎独静思 | 来源:发表于2021-10-14 22:57 被阅读0次

    binding adapters用来设置值,提供自定义的绑定逻辑等。
    当绑定的值发生变化时,绑定类会自动调用view的setter方法。我们可以提供自定义逻辑来选择调用的方法,也可以让data binding 库自动选择。

    自动方法选择

    比如对于名称为example的属性来说,库会自动setExample(arg)方法,在搜索过程中,只会考虑方法名称和参数,不考虑命名空间。
    例如,对于表达式android:text="@{user.name}",库会查找方法setText(arg),此方法接受的参数类型是user.getName()返回的类型。

     <android.support.v4.widget.DrawerLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:scrimColor="@{@color/scrim}"
        app:drawerListener="@{fragment.drawerListener}">
    

    对于存在setter方法,不存在对应属性的情况,data binding仍然起作用。我们可以给任意setter方法创建属性。比如DrawerLayout没有属性,但是有setter方法。上面的代码中就自动使用了setScrimColor(int) 和 setDrawerListener(DrawerListener)两个方法。

     @BindingMethods({
           @BindingMethod(type = "android.widget.ImageView",
                          attribute = "android:tint",
                          method = "setImageTintList"),
    })
    

    BindingMethod注解可以把属性和方法进行对应,比如上例中,我们把android:tint和setImageTintList关联在一起,而不是setTint()。

    提供自定义逻辑

    有些属性需要自定义的绑定逻辑,当对应属性值发生变化时触发自定义的逻辑。
    我们可以定义static的带有@BindingAdapter注解的方法来自定义绑定逻辑。

    @BindingAdapter("android:paddingLeft")
    public static void setPaddingLeft(View view, int padding) {
      view.setPadding(padding,
                      view.getPaddingTop(),
                      view.getPaddingRight(),
                      view.getPaddingBottom());
    }
    

    方法的第一个参数指当前的view,第二个参数代表binding表达式接受的参数。
    在binding adapter方法中,我们一次可以定义多个属性。

    @BindingAdapter({"imageUrl", "error"})
    public static void loadImage(ImageView view, String url, Drawable error) {
      Picasso.get().load(url).error(error).into(view);
    }
    
    <ImageView app:imageUrl="@{venue.imageUrl}" app:error="@{@drawable/venueError}" />
    

    此时,只有imageUrl和error同时使用的时候,loadImage才会触发。如果你希望,两者中任意一个值设置之后触发方法调用,那可以设置requireAll=false

    @BindingAdapter(value={"imageUrl", "placeholder"}, requireAll=false)
    public static void setImageUrl(ImageView imageView, String url, Drawable placeHolder) {
      if (url == null) {
        imageView.setImageDrawable(placeholder);
      } else {
        MyImageLoader.loadInto(imageView, url, placeholder);
      }
    }
    
    @BindingAdapter("android:paddingLeft")
    public static void setPaddingLeft(View view, int oldPadding, int newPadding) {
      if (oldPadding != newPadding) {
          view.setPadding(newPadding,
                          view.getPaddingTop(),
                          view.getPaddingRight(),
                          view.getPaddingBottom());
       }
    }
    

    我们可以同时在方法中处理旧值和新值,对于只有一个方法的接口或抽象类也可以这样使用,但是如果多余一个方法,则需要拆成多个类。

    @BindingAdapter("android:onLayoutChange")
    public static void setOnLayoutChangeListener(View view, View.OnLayoutChangeListener oldValue,
           View.OnLayoutChangeListener newValue) {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        if (oldValue != null) {
          view.removeOnLayoutChangeListener(oldValue);
        }
        if (newValue != null) {
          view.addOnLayoutChangeListener(newValue);
        }
      }
    }
    

    对象转换

    如果binding表达式中返回一个object,那系统会查找对应的方法,并自动的转换为对应类型的参数。如果方法接受的参数也是模糊的,那需要自定义转换。
    比如,一个属性值接受Drawable,但你提个的是int,这时候就需要转换。

     <View
       android:background="@{isError ? @color/red : @color/white}"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>
    
    @BindingConversion
    public static ColorDrawable convertColorToDrawable(int color) {
        return new ColorDrawable(color);
    }
    

    在这个方法中,需要返回一个对应类型的值。

    相关文章

      网友评论

          本文标题:DataBinding学习(下)

          本文链接:https://www.haomeiwen.com/subject/roproltx.html