/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.imagepipeline.animated.base;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.view.animation.LinearInterpolator;
import com.facebook.common.internal.VisibleForTesting;
import com.facebook.common.logging.FLog;
import com.facebook.common.references.CloseableReference;
import com.facebook.common.time.MonotonicClock;
import com.facebook.drawable.base.DrawableWithCaches;
import com.nineoldandroids.animation.ValueAnimator;
/**
* A {@link Drawable} that renders a animated image. The details of the format are abstracted by the
* {@link AnimatedDrawableBackend} interface. The drawable can work either as an {@link Animatable}
* where the client calls start/stop to animate it or it can work as a level-based drawable where
* the client drives the animation by calling {@link Drawable#setLevel}.
*/
public class AnimatedDrawableSupport extends AbstractAnimatedDrawable
implements AnimatableDrawableSupport {
public AnimatedDrawableSupport(
ScheduledExecutorService scheduledExecutorServiceForUiThread,
AnimatedDrawableCachingBackend animatedDrawableBackend,
AnimatedDrawableDiagnostics animatedDrawableDiagnostics,
MonotonicClock monotonicClock) {
super(scheduledExecutorServiceForUiThread,
animatedDrawableBackend,
animatedDrawableDiagnostics,
monotonicClock);
}
@Override
public ValueAnimator createValueAnimator(int maxDurationMs) {
ValueAnimator animator = createValueAnimator();
int repeatCount = Math.max((maxDurationMs / getAnimatedDrawableBackend().getDurationMs()), 1);
animator.setRepeatCount(repeatCount);
return animator;
}
@Override
public ValueAnimator createValueAnimator() {
int loopCount = getAnimatedDrawableBackend().getLoopCount();
ValueAnimator animator = new ValueAnimator();
animator.setIntValues(0, getDuration());
animator.setDuration(getDuration());
animator.setRepeatCount(loopCount != 0 ? loopCount : ValueAnimator.INFINITE);
animator.setRepeatMode(ValueAnimator.RESTART);
animator.setInterpolator(new LinearInterpolator());
animator.addUpdateListener(createAnimatorUpdateListener());
return animator;
}
@Override
public ValueAnimator.AnimatorUpdateListener createAnimatorUpdateListener() {
return new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
setLevel((Integer) animation.getAnimatedValue());
}
};
}
}