BindingAdapter LiveData first value always null

Erk*_*kan 6 android kotlin android-binding-adapter android-livedata

I'm trying to handle a LiveData value (profilePicture: Bitmap) within a BindingAdapter function but the first value is always null. The binding adapter is a ViewSwitcher with ProgressBar and ImageView.

Getting profile picture from firebase like this:

    val downloadPictureResult = MutableLiveData<Bitmap>()
    // ...
   fun downloadProfilePic(): LiveData<Bitmap?> {
        val imageRef = storage.getReference("images/$uid/profile/profile_picture.jpg")
        imageRef.getBytes(ONE_MEGABYTE).addOnCompleteListener { task ->
            if (task.isSuccessful) {
                //...
                downloadPictureResult.value =  responseBitmap
                //...
            } else {
                downloadPictureResult.value = null
                Log.d(TAG, task.exception?.localizedMessage)
            }
        }
        return downloadPictureResult;
    }

Run Code Online (Sandbox Code Playgroud)

Because the first value is null and the second the expected bitmap object, the view.showNext()is called two times. But it's more important for me to understand why the firstvalue is null because the setProfilePicture method will have some more logic.

BindingAdapter looks like this.

fun setProfilePicture(view: ViewSwitcher, profilePicture: Bitmap?) {
 Log.d("PPSS", profilePicture.toString())
    val imageView: ImageView = view[1] as ImageView
    imageView.setImageDrawable(view.context.getDrawable(R.drawable.account_circle_24dp))

    profilePicture.let { picture ->
        if (picture != null) {
            val rounded = RoundedBitmapDrawableFactory.create(view.resources, picture)
            rounded.isCircular = true
            imageView.setImageDrawable(rounded)
            view.showNext()
        } else {
            view.showNext()
        }
    }

Run Code Online (Sandbox Code Playgroud)

Log:

2019-04-13 17:53:01.658 11158-11158/... D/PPSS: null
2019-04-13 17:53:02.891 11158-11158/... D/PPSS: android.graphics.Bitmap@8b6ecb8
Run Code Online (Sandbox Code Playgroud)

Jul*_*ñas 5

When you define a LiveData, its initial value will be null even when its type is not nullable:

val downloadPictureResult = MutableLiveData<Bitmap>()
// Here, downloadPictureResult.value is null
Run Code Online (Sandbox Code Playgroud)

In your case, the value of the LiveData returned by downloadProfilePic() will be null until the picture is downloaded, which will happen asynchronously inside the callback addOnCompleteListener:

fun downloadProfilePic(): LiveData<Bitmap?> {
    ...
    imageRef.getBytes(ONE_MEGABYTE).addOnCompleteListener { task ->
        ...
        // This happens asynchronously, likely after downloadProfilePic()
        // has already returned
        downloadPictureResult.value =  responseBitmap
        ...
    }

    return downloadPictureResult;
}
Run Code Online (Sandbox Code Playgroud)

That's why the first value that gets passed to your adapter is null, because downloadPictureResult.value is still null at the time when downloadPictureResult is returned by downloadProfilePic() for the first time.