Transitions
- About
- Default transition
- Standard behavior
- Specifying Transitions
- Performance Tips
- Common Errors
- Custom Transitions
About
Transitions
in Glide allow you to define how Glide should transition from a placeholder to a newly loaded image or from a thumbnail to a full size image. Transitions act within the context of a single request, not across multiple requests. As a result, Transitions
do NOT allow you to define an animation (like a cross fade) from one request to another request.
Default transition
Unlike Glide v3, Glide v4 does NOT apply a cross fade or any other transition by default. Transitions must be applied manually per request.
Standard behavior
Glide provides a number of transitions that users can manually apply per request. Glide’s built in transitions behave in a consistent manner and will avoid running in certain circumstances depending on where images are loaded from.
Images can be loaded from one of four places in Glide:
- Glide’s in memory cache
- Glide’s disk cache
- A source File or Uri available locally on the device
- A source Url or Uri available only remotely.
Glide’s built in transitions do not run if data is loaded from Glide’s in memory cache. However, Glide’s built in transitions do run if data is loaded from Glide’s disk cache, a local source File or Uri or a remote source Url or Uri.
To change this behavior and write your own custom transition, see the custom transitions section below.
Specifying Transitions
For an overview and code sample, see the Options documentation.
TransitionOptions
are used to specify the transitions for a particular request. TransitionOptions
are set for a request using the transition()
method in RequestBuilder
. Type specific transitions can be specified using BitmapTransitionOptions
or DrawableTransitionOptions
. For types other than Bitmaps
and Drawables
GenericTransitionOptions
can be used.
Performance Tips
Animations in Android can be expensive, particularly if a large number are started at once. Cross fades and other animations involving changes in alpha can be especially expensive. In addition, animations often take substantially longer to run than images take to decode. Gratuitous use of animations in lists and grids can make image loading feel slow and janky. To maximize performance, consider avoiding animations when using Glide to load images into ListViews, GridViews, or RecyclerViews, especially when you expect images to be cached or fast to load most of the time. Instead consider pre-loading so that images are in memory when users scroll to them.
Common Errors
Cross fading with placeholders and transparent images
Glide’s default cross fade animation leverages TransitionDrawable
. TransitionDrawable
offers two animation modes, controlled by setCrossFadeEnabled()
. When cross fades are disabled, the image that is transitioned to is faded in on top of the image that was already showing. When cross fades are enabled, the image that is being transitioned from is animated from opaque to transparent and the image that is being transitioned to is animated from transparent to opaque.
In Glide, we default to disabling cross fades because it typically provides a much nicer looking animation. An actual cross fade where the alpha of both images is changing at once often produces a white flash in the middle of the animation where both images are partially opaque.
Unfortunately although disabling cross fades is typically a better default, it can also lead to problems when the image that is being loaded contains transparent pixels. When the placeholder is larger than the image that is being loaded or the image is partially transparent, disabling cross fades results in the placeholder being visible behind the image after the animation finishes. If you are loading transparent images with placeholders, you can enable cross fades by adjusting the options in DrawableCrossFadeFactory
and passing the result into transition()
:
DrawableCrossFadeFactory factory =
new DrawableCrossFadeFactory.Builder().setCrossFadeEnabled(true).build();
GlideApp.with(context)
.load(url)
.transition(withCrossFade(factory))
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(R.color.placeholder)
.into(imageView);
See Issue #2017 for more information. Thanks @minas90 for writing down the example above.
Cross fading across requests.
Transitions
do not allow you to cross fade between two different images that are loaded with different requests. Glide by default will cancel any existing requests when you start a new load into an existing View or Target (See Targets documentation for more details). As a result, if you want to load two different images and cross fade between them, you cannot do so with Glide directly. Strategies like waiting for the first load to finish, grabbing a Bitmap or Drawable out of the View, starting a second load, and then manually animating between the Drawale or Bitmap and the new image are unsafe and may result in crashes or graphical corruption.
Instead, the easiest way to cross fade across two different images loaded in two separate requests is to use ViewSwitcher
containing two ImageViews
. Load the first image into the result of getNextView()
. Then load the second image into the next result of getNextView()
and use a RequestListener
to call showNext()
when the second image load finishes. For better control, you can also follow the strategy outlined in the developer documentation. As with the ViewSwitcher
, only start the cross fade after the second image load finishes.
Custom Transitions
To define a custom transition:
- Implement
TransitionFactory
. - Apply your custom
TransitionFactory
to loads withDrawableTransitionOptions#with
.
To change the default behavior of your transition so that you can control whether or not it’s applied when your image is loaded from the memory cache, disk cache or from source,
you can inspect the DataSource
passed in to the build()
method in your TransitionFactory
,
For an example, see DrawableCrossFadeFactory
.