Android DataBinding学习(四):@BindingAdapter的使用(Kotlin版本)

Android DataBinding学习(四):@BindingAdapte的使用

一.前言

前面的三篇文章主要是讲了如何将数据和UI界面绑定,通过这种技术可以轻松解决数据更新到UI界面,减少Activity代码量。但是,之前的技术只能在View内置的已有属性上使用,比如setText和getText。如果你需要在自定义的属性上以及View的内置属性上进行扩展,你就需要使用@BindingAdapter
接下来,我将用Glide+@BindingAdapter来完成一个下载图片的小功能

二.@BindingAdapter的使用

单参数情况

自定义属性:
首先自定义一个属性来加载图片,自定义属性的类:

class ImageLoader {
    
    

    companion object{
    
    

        @JvmStatic
        @BindingAdapter(value = ["loadImage"])
        fun loadImage(imageView: ImageView, loadUrl:String){
    
    
            Glide.with(imageView)
                .load(loadUrl)
                .into(imageView)
        }
    }
}

从上面代码可以看到:

  1. 要实现自定义属性加载图片需要用到@BindingAdapter注解,通过value设置自定义属性的名称,同时value的值决定UI界面的自定义属性的名称,比如UI界面中就是app:loadImage
  2. value是一个字符串数组,可以接受多个参数。如果这里是用kotlin编写的,所以用[]取代Java的{}。(注意:这里如果是Java用{})。
  3. loadImage必须是一个public static的方法,在kotlin中如何表示呢?如同上面代码所示,你需要加上@JvmStatic同时在companion object伴生对象中。事实上,如果你反编译成Java后是这样的public static final void loadImage(){}
  4. 第一个参数必须是需要自定义属性的那个View,比如这里是ImageView。事实上,我的需求是在ImageView上新增一个能加载网络图片的属性,所以这里的第一个参数就是ImageView。同理,如果你想在TextView上扩展一个属性,那么第一个参数肯定就是TextView。

UI界面

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

    <data>
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/show_image"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_margin="5dp"
            app:loadImage="@{`https://cn.bing.com/sa/simg/hpb/LaDigue_EN-CA1115245085_1920x1080.jpg`}"
            app:layout_constraintDimensionRatio="16:9"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

这里的写法和之前有点不一样,之前由于需要和数据绑定,<data></data>里面会有需要加载的数据。这里不需要绑定额外额数据,所以只需要<data></data>即可。

Activity:

class LoadImageActivity:AppCompatActivity() {
    
    
    var binding:ActivityLoadImageBinding? = null

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_load_image)
    }
}

这里更加简单,通过DataBindingUtil.setContentView绑定下UI界面就行了。

多参数情况

在实际的开发中,加载图片中间会一般先展示占位图,加载错误会有错误显示图。那么这些属性如何能同时展示在ImageView上呢?上面提到@BindingAdapter的value是一个字符串数组,那么我们就可以利用这个来解决展示多个属性的问题。
kotlin代码:

class ImageLoader {
    
    

    companion object{
    
    

		// 第一种,requireAll默认为true
        @JvmStatic
        @BindingAdapter(value = ["placeHolder", "error", "loadImage"])
        fun loadImage(imageView: ImageView, placeHolder:Drawable, error:Drawable, loadUrl:String){
    
    
            Glide.with(imageView)
                .load(loadUrl)
                .apply(RequestOptions().placeholder(placeHolder).error(error))
                .into(imageView)
        }
        
		// 第二种,requireAll设置为false
		// 注意这里的参数都加上了'?'空安全操作符
		@JvmStatic
        @BindingAdapter(value = ["placeHolder", "error", "loadImage"], requireAll = false)
        fun loadImage(imageView: ImageView, placeHolder:Drawable?, error:Drawable?, loadUrl:String?){
    
    
            Glide.with(imageView)
                .load(loadUrl)
                .apply(RequestOptions().placeholder(placeHolder).error(error))
                .into(imageView)
        }
    }
}

以上代码在编译的时候需要有以下几点需要注意:

  1. 这里需要注意value数组的"属性名称"的顺序一定要和参数的顺序一一对应上,要不然会出现编译错误的问题。
  2. @BindingAdapter有个参数"requireAll",如果设置为true(默认是true),那么以上的三个属性必须全部都要使用在UI界面上,如果设置为false,那么就不需要三个属性必须全部都要使用。
  3. 注意上面的除了imageView参数都需要加上"空字符串安全符"具体原因可以参考这篇文章记录bug:Kotlin+@BindingAdapter的一个bug

三.总结

通过@BindingAdapter可以实现自定义属性和数据的绑定,同时实现数据更新可以直接体现到UI界面上(单向绑定)。那么,既然有单向绑定,比如也会有自定义属性的双向绑定,下一篇文章,将实现自定义属性的双向绑定。

猜你喜欢

转载自blog.csdn.net/RQ997832/article/details/122651967
今日推荐