bumptech / glide

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

Transcoded Target not showing placeholder images #373

Closed dageforce closed 9 years ago

dageforce commented 9 years ago

I have written a transcoder to generate a palette for a bitmap and return an object containing both the bitmap and the object to a custom target that extends ImageViewTarget:

public class PaletteImageViewTarget extends ImageViewTarget<PaletteBitmapWrapper> {
    public PaletteImageViewTarget (ImageView view) {
        super(view);
    }

    @Override
    protected void setResource(PaletteBitmapWrapper paletteBitmapWrapper) {
        view.setImageBitmap(paletteBitmapWrapper.getBitmap());
    }
}

The problem is any error or placeholder requests seems to be ignored? Any help would be greatly appreciated, Thank you :)

sjudd commented 9 years ago

That's actually relatively surprising, ImageViewTarget should set placeholders: https://github.com/bumptech/glide/blob/master/library/src/main/java/com/bumptech/glide/request/target/ImageViewTarget.java.

If you override onLoadStarted/onLoadFailed as well, are they called with the drawables you expect?

Also can you fill out the rest of the issue template?

dageforce commented 9 years ago

Glide Version: 3.5.2

Device/Android Version: This is happening on all the devices I have tested on so far.

Issue details/Repro steps: I have checked the onLoadStarted/OnLoadFailed and it seems not to pass the drawable when I am transcoding the image (both returns null)

Glide load line:

request.transcode(PaletteBitmapTranscoder.getInstance(), PaletteBitmapWrapper.class).into(new PaletteBitmapImageViewTarget(mImageView) {
                @Override
                public void onResourceReady(PaletteBitmapWrapper resource, GlideAnimation<? super PaletteBitmapWrapper> glideAnimation) {
                   //do something with generated resource.getPalette();
                }
            });

Thank you.

TWiStErRob commented 9 years ago

Just a sanity check: did you call .load()? (it's not clear from the amount of code, i.e. What is request?)

dageforce commented 9 years ago

My apologies, I have a local request builder class. This is what a full request, that would not have a placeholder resource, would look like (I have tried using both placeholderId and placeholderDrawable) :

Glide.load(mUri).asBitmap().placeholder(mPlaceholderResId).error(mErrorResId).listener(new RequestListener() {
                @Override
                public boolean onException(Exception e, Object model, Target target, boolean isFirstResource) {
                    mCallback.onError();
                    return false;
                }

                @Override
                public boolean onResourceReady(Object resource, Object model, Target target, boolean isFromMemoryCache, boolean isFirstResource) {
                    mCallback.onSuccess(model);
                    return false;
                }
            }).transcode(PaletteBitmapTranscoder.getInstance(), PaletteBitmapWrapper.class).into(new PaletteBitmapImageViewTarget(mImageView) {
                @Override
                public void onResourceReady(PaletteBitmapWrapper resource, GlideAnimation<? super PaletteBitmapWrapper> glideAnimation) {
                   //do something with generated resource.getPalette();
                }
            });
sjudd commented 9 years ago

I'd still suspect something with your Target class. Placeholder and error are almost entirely independent of the type of thing you're loading. If you just try to get the corresponding drawable from resources is it non-null? If you remove the transcode line, are onLoadStarted/cleared called with the placeholders you expect?

Can you maybe reproduce this in a simple sample app? It might be a little hard to track down otherwise.

dageforce commented 9 years ago

I will try and write a little test app if I get some time in the future. Thus far it seems that if I remove the transcode from the request and give my target a bitmap response type, that everything works normally. As soon as a add transcode and have my target expect my "wrapper" object, no error or place holder images are passed through.

TWiStErRob commented 9 years ago

I just remembered that there are two "transcode" methods: .transcoder(transcoder) and .transcode(transcoder, class). The first one just sets the transcoder, but the second one (you're using) resets (copies) the builder. That should be used in the very beginning of a request build process.

@dageforce You have to call .placeholder() and .error() AFTER transcode(transcoder, class).

@sjudd is it a bug or intentional that GenericRequestBuilder copy-ctor doesn't copy the placeholder, error, transformation, override, sizeMultiplier, etc...?

sjudd commented 9 years ago

@TWiStErRob Nice find! I'd forgotten about the difference between the two.

It's actually intentional. In fact you're not supposed to be able to call transcode(transcoder, class) except as one of the first calls to the builder, prior to setting any other options. That method is only available on GenericTranscodeRequest, which itself is only available from one relatively obscure method. All of the standard methods in GenericTranscodeRequest just return a GenericRequestBuilder which doesn't contain that method. Internally the same request is returned, so with casting you could make it work, but you're not supposed to do so.

TWiStErRob commented 9 years ago

This was one of the first problems I ran into with SVG, the order of calls, but there was only one compiling order. If he's not casting or hacking around, how come the method is available after specifying everything except .into()? Is it maybe RequestListener's lack of generic arguments?

dageforce commented 9 years ago

Thanks, this assisted me in resolving my issue :)

sjudd commented 9 years ago

I looked into this just now, I can't find any way to get the syntax with transcode after listener() to compile. That method is only available on BitmapTypeRequest, which is only returned from asBitmap(). All subsequent methods on BitmapTypeRequest return a BitmapRequestBuilder.

It's possible via casting to get around that, since it is just the same object, but I don't think there's an API issue here. If someone can provide a compiling snippet of code that proves me wrong I'll definitely take another look.