bumptech / glide

An image loading and caching library for Android focused on smooth scrolling
https://bumptech.github.io/glide/
Other
34.62k stars 6.12k forks source link

Image not getting load while listener added #5083

Open aniladhikary7 opened 1 year ago

aniladhikary7 commented 1 year ago

Glide Version: 1.0.0-alpha.1

Integration libraries: com.github.bumptech.glide:compose:1.0.0-alpha.1

I am using GlideImage to load from local and url resource.

I need my callbacks(onError and onSuccess) to return if url fails to load or succeed to load. For this added inside the body of glide added the listener. As listener added image not getting loaded.

My requirements are callBacks(onError and onSuccess) to return along with image load. Please help me by your idea to resolve my challenge.

Below my code attached:

Glide load line / GlideModule (if any) / list Adapter code (if any):

Glide.with...

GlideImage(
                model = src,
                contentDescription = "image load",
                modifier = Modifier.fillMaxSize(),
            ) {
                it
                    .listener(object : RequestListener<Drawable> {
                        override fun onLoadFailed(
                            e: GlideException?,
                            model: Any?,
                            target: Target<Drawable>?,
                            isFirstResource: Boolean
                        ): Boolean {
                            Log.e("Glide","Failure")
                            state = ImageState.error
                            onError?.invoke()
                            return true
                        }

                        override fun onResourceReady(
                            resource: Drawable?,
                            model: Any?,
                            target: Target<Drawable>?,
                            dataSource: DataSource?,
                            isFirstResource: Boolean
                        ): Boolean {
                            Log.e("Glide","Success")
                            state = ImageState.success
                            onLoad?.invoke()
                            return true
                        }
                    })
            }
catherineboyce commented 1 year ago

First, see if img.complete is checked; if so, remove the event handler and call the function. That is done to avoid missed calls. Although the browser is not single-threaded, there is just one core JavaScript thread. It would be entirely OK for the browser to see that it has finished loading the image between those two lines, look for handlers for the load event, not see any, and set complete — and you wouldn't get a callback at all — if we checked complete first and added the handler on the next line. Although extremely unlikely, it is possible. bloxorz The aforementioned may, in extremely rare circumstances, call img_loaded twice for the same image for the same reason. Therefore, you need to handle the function's potential for being called already.

sudipta383 commented 1 year ago

Hi there! I noticed that you're having trouble getting your onSuccess and onError callbacks to return along with your image load when using GlideImage. I understand how important it is to keep track of the image loading performance in the app, so I'd be happy to help you out.

To start, I would recommend checking whether you're adding the listener in the correct location. Sometimes, adding the listener inside the body of Glide can interfere with image loading. Instead, try adding the listener directly to the GlideImage component like this:

GlideImage( model = src, contentDescription = "image load", modifier = Modifier.fillMaxSize(), onRequestCompleted = { drawable, , -> // onSuccess callback logic here }, onRequestError = { , -> // onError callback logic here } )

This should allow you to receive both the image and the callbacks you need. Let me know if this helps or if you have any other questions!

PMARZV commented 10 months ago

@sudipta383 how can i do this in the current version of Glide Image Compose? Because i have a Glide Image (with a remember model url) inside a Lazy column and every time the item appears, override fun onResourceReady is called again and i have some code inside it that its running again when it shouldnt... any workaround?

val model  = remember  { if(song?.album?.images?.isNotEmpty() == true) song.album.images[0].url else "" }
 GlideImage(
                                    model = model,
                                    contentDescription = "Track Image",
                                    modifier = Modifier
                                        .fillMaxWidth(0.55f)

                                        .aspectRatio(1f)
                                        .shadow(elevation = 10.dp),
                                  transition = CrossFade(animationSpec = tween(450)),

                                    loading = placeholder(R.drawable.default_album_art),

                                ){

                                it.addListener(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 {
//WHEN ITEM LAZY COLUMN APPEARS THIS IS CALLED AGAIN
                              val drawable  = resource as BitmapDrawable
                                        val bitmap  = drawable.bitmap

                                        val palette = Palette.from(bitmap).generate()
                                        palette.apply {
                                            val listColors = listOf(
                                                vibrantSwatch,
                                                darkVibrantSwatch,
                                                lightVibrantSwatch,
                                                lightMutedSwatch,
                                                mutedSwatch,
                                                darkMutedSwatch
                                            )

                                            for (i in 0..listColors.size) {

                                                val y = listColors[i]
                                                if (y != null) {
                                                    var colorprefinal = Color(y.rgb)

                                                    while(!colorprefinal.toArgb().canDisplayOnBackground(colorBackground)) {

                                                        Log.d("WHILELOOPCALLED", isDark.toString())

                                                        when (isDark) {
                                                            true -> colorprefinal =  Color(colorprefinal.toArgb().adjustForBackground(colorBackground, false))
                                                            false ->  colorprefinal = Color(colorprefinal.toArgb().adjustForBackground(colorBackground, true))
                                                        }

                                                    }

                                                    color = colorprefinal

                                                    break
                                                }

                                            }

                                        }

                                        return false

                                    }

                                })
                            }