1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
package com.bumptech.glide.request.animation;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
/**
* A cross fade {@link GlideAnimation} for {@link android.graphics.drawable.Drawable}s
* that uses an {@link android.graphics.drawable.TransitionDrawable} to transition from an existing drawable
* already visible on the target to a new drawable. If no existing drawable exists, this class can instead fall back
* to a default animation that doesn't rely on {@link android.graphics.drawable.TransitionDrawable}.
*/
public class DrawableCrossFadeViewAnimation<T extends Drawable> implements GlideAnimation<T> {
// 150 ms.
public static final int DEFAULT_DURATION = 300;
private Animation defaultAnimation;
private int duration;
private static Animation getDefaultAnimation() {
AlphaAnimation animation = new AlphaAnimation(0f, 1f);
animation.setDuration(DEFAULT_DURATION / 2);
return animation;
}
/**
* A factory class that produces a new {@link GlideAnimation} that varies depending
* on whether or not the drawable was loaded from the memory cache and whether or not the drawable is the first
* image to be set on the target.
*
* <p>
* Resources are usually loaded from the memory cache just before the user can see the view,
* for example when the user changes screens or scrolls back and forth in a list. In those cases the user
* typically does not expect to see an animation. As a result, when the resource is loaded from the memory
* cache this factory producdes an {@link NoAnimation}.
* </p>
*/
public static class DrawableCrossFadeFactory<T extends Drawable> implements GlideAnimationFactory<T> {
private Context context;
private int defaultAnimationId;
private Animation defaultAnimation;
private int duration;
private DrawableCrossFadeViewAnimation<T> animation;
public DrawableCrossFadeFactory() {
this(getDefaultAnimation(), DEFAULT_DURATION);
}
public DrawableCrossFadeFactory(int duration) {
this(getDefaultAnimation(), duration);
}
public DrawableCrossFadeFactory(Context context, int defaultAnimationId, int duration) {
this.context = context;
this.defaultAnimationId = defaultAnimationId;
this.duration = duration;
}
public DrawableCrossFadeFactory(Animation defaultAnimation, int duration) {
this.defaultAnimation = defaultAnimation;
this.duration = duration;
}
@Override
public GlideAnimation<T> build(boolean isFromMemoryCache, boolean isFirstImage) {
if (isFromMemoryCache) {
return NoAnimation.get();
}
if (animation == null) {
if (defaultAnimation == null) {
defaultAnimation = AnimationUtils.loadAnimation(context, defaultAnimationId);
}
animation = new DrawableCrossFadeViewAnimation<T>(defaultAnimation, duration);
}
return animation;
}
}
/**
* Constructor that takes a default animation and a duration in milliseconds that the cross fade animation should
* last.
* @param defaultAnimation The default animation that will run if there is nothing to cross fade from when a new
* {@link android.graphics.drawable.Drawable} is set.
* @param duration The duration that the cross fade animation should run if there is something to cross fade from
* when a new {@link android.graphics.drawable.Drawable} is set.
*/
public DrawableCrossFadeViewAnimation(Animation defaultAnimation, int duration) {
this.defaultAnimation = defaultAnimation;
this.duration = duration;
}
/**
* Animates from the previous drawable to the current drawable in one of two ways.
*
* <ol>
* <li>Using the default animation provided in the constructor if the previous drawable is null</li>
* <li>Using the cross fade animation with the duration provided in the constructor if the previous
* drawable is non null</li>
* </ol>
*
* @param previous The previous drawable that is currently being displayed in the {@link android.view.View}.
* @param current The new drawable that should be displayed in the {@link com.bumptech.glide.request.target.Target}
* after this animation completes.
* @param view The {@link android.widget.ImageView} the animation should run on.
* @return true if in the process of running the animation the current drawable is set on the view, false if the
* current drawable must be set on the view manually by the caller of this method.
*/
@Override
public boolean animate(Drawable previous, T current, ImageView view) {
if (previous != null) {
TransitionDrawable transitionDrawable = new TransitionDrawable(new Drawable[] { previous, current });
transitionDrawable.setCrossFadeEnabled(true);
transitionDrawable.startTransition(duration);
view.setImageDrawable(transitionDrawable);
return true;
} else {
view.startAnimation(defaultAnimation);
return false;
}
}
}
|