1 package com.airbnb.lottie.value; 2 3 4 import androidx.annotation.Nullable; 5 import androidx.annotation.RestrictTo; 6 7 import com.airbnb.lottie.LottieAnimationView; 8 import com.airbnb.lottie.LottieDrawable; 9 import com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation; 10 11 /** 12 * Allows you to set a callback on a resolved {@link com.airbnb.lottie.model.KeyPath} to modify 13 * its animation values at runtime. 14 * 15 * If your dynamic property does the following, you must call {@link LottieAnimationView#invalidate()} or 16 * {@link LottieDrawable#invalidateSelf()} each time you want to update this value. 17 * 1. Use {@link com.airbnb.lottie.RenderMode.SOFTWARE} 18 * 2. Rendering a static image (the animation is either paused or there are no values 19 * changing within the animation itself) 20 * When using software rendering, Lottie caches the internal rendering bitmap. Whenever the animation changes 21 * internally, Lottie knows to invalidate the bitmap and re-render it on the next frame. If the animation 22 * never changes but your dynamic property does outside of Lottie, Lottie must be notified that it changed 23 * in order to set the bitmap as dirty and re-render it on the next frame. 24 */ 25 public class LottieValueCallback<T> { 26 private final LottieFrameInfo<T> frameInfo = new LottieFrameInfo<>(); 27 @Nullable private BaseKeyframeAnimation<?, ?> animation; 28 29 /** 30 * This can be set with {@link #setValue(Object)} to use a value instead of deferring 31 * to the callback. 32 **/ 33 @Nullable protected T value = null; 34 LottieValueCallback()35 public LottieValueCallback() { 36 } 37 LottieValueCallback(@ullable T staticValue)38 public LottieValueCallback(@Nullable T staticValue) { 39 value = staticValue; 40 } 41 42 /** 43 * Override this if you haven't set a static value in the constructor or with setValue. 44 * <p> 45 * Return null to resort to the default value. 46 * 47 * Refer to the javadoc for this class for a special case that requires manual invalidation 48 * each time you want to return something different from this method. 49 */ 50 @Nullable getValue(LottieFrameInfo<T> frameInfo)51 public T getValue(LottieFrameInfo<T> frameInfo) { 52 return value; 53 } 54 setValue(@ullable T value)55 public final void setValue(@Nullable T value) { 56 this.value = value; 57 if (animation != null) { 58 animation.notifyListeners(); 59 } 60 } 61 62 @RestrictTo(RestrictTo.Scope.LIBRARY) 63 @Nullable getValueInternal( float startFrame, float endFrame, T startValue, T endValue, float linearKeyframeProgress, float interpolatedKeyframeProgress, float overallProgress )64 public final T getValueInternal( 65 float startFrame, 66 float endFrame, 67 T startValue, 68 T endValue, 69 float linearKeyframeProgress, 70 float interpolatedKeyframeProgress, 71 float overallProgress 72 ) { 73 return getValue( 74 frameInfo.set( 75 startFrame, 76 endFrame, 77 startValue, 78 endValue, 79 linearKeyframeProgress, 80 interpolatedKeyframeProgress, 81 overallProgress 82 ) 83 ); 84 } 85 86 @RestrictTo(RestrictTo.Scope.LIBRARY) setAnimation(@ullable BaseKeyframeAnimation<?, ?> animation)87 public final void setAnimation(@Nullable BaseKeyframeAnimation<?, ?> animation) { 88 this.animation = animation; 89 } 90 } 91