Reputation: 2086
I have a use case for Glide (the image caching library for Android) that isn't typical - for each item in a ListView
, I need to display a thumbnail if it's cached - if not, I need to generate one (as opposed to download one) using a custom Bitmap
renderer.
Looking at the documentation, I see a lot discussions on decoding and transcoding, but my use case doesn't really fall into either of the two. I need Glide to pass an identifier to the renderer - the renderer will check the datastore and generate a Bitmap
as appropriate. There is no stream to speak of.
I'm looking for an example on how this can be accomplished.
Upvotes: 2
Views: 4185
Reputation: 7387
What you want to do is possible, although support for custom decoders wasn't a huge goal of Glide 3.0 (it will be for 4.0), so the process is a bit clunky.
Glide's code and samples provide two examples of how this works. For a custom resource type, take a look at the SVG sample. For a custom model type and a custom decoder, take a look at the code used to decode Gif frames. From your description, it sounds like the Gif frame example is probably more relevant.
Assuming I understand what you want to do, you need to define and provide two interfaces.
First you need to define a ModelLoader. Traditionally ModelLoaders are used to retrieve data. If that's not necessary (ie you can decode your Bitmap from your identifier alone) you can follow the Gif frame example above and simply pass through your identifier.
Second you need to define a ResourceDecoder. Your ResourceDecoder will take the identifier, check the data store, generate a Bitmap, and then return a new BitmapResource.
Since you're decoding a resource type that Glide knows about, you can then pass in Glide's BitmapEncoder and StreamBitmapDecoder if you want to support disk caching, any one of Glide's BitmapTransformations if you wan to apply a transformation, and finally you can use Glide's BitmapImageViewTarget to specify how to load the Bitmap into the view.
The entire load call will look something like this:
Glide.with(fragment)
.using(new YourModelLoader(), YourIdentifier.class)
.load(yourIdentifier)
.as(Bitmap.class)
.decoder(new YourBitmapDecoder())
.cacheDecoder(new FileToStreamDecoder(new StreamBitmapDecoder())
.encoder(new BitmapEncoder())
.transform(new CenterCrop())
.into(new BitmapImageViewTarget(yourView);
Since that's a lot of stuff to specify, you can also define the builder once and re-use it for to load multiple identifiers:
builder = Glide.with(fragment)
.using(new YourModelLoader(), YourIdentifier.class)
.as(Bitmap.class)
.decoder(new YourBitmapDecoder())
.cacheDecoder(new FileToStreamDecoder(new StreamBitmapDecoder())
.encoder(new BitmapEncoder())
.transform(new CenterCrop());
// At some point later:
builder
.load(firstIdentifier)
.into(new BitmapImageViewTarget(firstView));
builder
.load(secondIdentifier)
.into(new BitmapImageViewTarget(secondView));
Glide 4.0 will help alleviate some of the boilerplate by allowing you to register new components and use existing builders, rather than forcing you to provide each part individually and use only the GenericRequestBuilder.
Upvotes: 3