Search code examples
androidkotlinimageviewandroid-drawable

Returns null when trying to get drawable from ImageView


I'm trying to solve a problem with getting the dominant color in an image, but I can't convert it to a bitmap, because I get null all the time. What could the problem be?

View itself in XML:

<androidx.appcompat.widget.AppCompatImageView
    android:id="@+id/ivIcon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintCircleRadius="8dp"
    app:srcCompat="@drawable/icon_default"
    tools:srcCompat="@drawable/icon_default" />

Getting the image goes through Glide by loading the image by url (fun loadInto (...)) and after that I try to get the drawable:


viewLifecycleOwner.lifecycleScope.launchWhenStarted {
    viewOutput.iconFlow.collect { photoUrl ->
        if (url != null) {
            loadInto(url, binding.Icon)
            getDominantColor(binding.ivIcon) <- null here
        }
    }
}

Update:

private fun getDominantColor(image: AppCompatImageView) {
        val bitmap: Bitmap = (image.drawable as BitmapDrawable).bitmap
        Palette.from(bitmap).generate { palette ->
            val dom: Int = palette!!.getDominantColor(0x000000)
            setGradientColor(dom)
        }
    }
    fun loadInto(
        url: String,
        imageView: ImageView,
        placeHolder: Int = 0,
        errorHolder: Int = 0,
    ) {
        Glide
            .with(imageView)
            .load(url)
            .run { if (placeHolder != 0) placeholder(placeHolder) else this }
            .run { if (errorHolder != 0) error(errorHolder) else this }
            .into(imageView)
    }

Solution

  • As mentioned by @Lino, Glide will make an asynchronous call to get the image. This will take some time and it may return null if you get the Bitmap from the ImageView right after it.

    Your attempt to create a listener callback is correct. And if it is properly implemented, onResourceReady() method should be called once ready. You may refer the sample below:

    Glide
        .with(this@MainActivity)
        .load(url)
        .run { this }
        .run { this }
        .listener(object : RequestListener<Drawable> {
            override fun onLoadFailed(
                e: GlideException?,
                model: Any?,
                target: Target<Drawable>?,
                isFirstResource: Boolean
            ): Boolean {
                return false
            }
    
            override fun onResourceReady(
                resource: Drawable?,
                model: Any?,
                target: Target<Drawable>?,
                dataSource: DataSource?,
                isFirstResource: Boolean
            ): Boolean {
                // Process with your bitmap in callback here
                Palette.from((resource!! as BitmapDrawable).bitmap).generate { palette ->
                    val dom: Int = palette!!.getDominantColor(0x000000)
                    setGradientColor(dom)
                }
                return false
            }
        })
        .into(ivIcon)