Добавлен Drawable для плавных переходов

This commit is contained in:
Victor 2015-05-05 01:42:55 +03:00
parent 2218b6d07b
commit a3a20a05b5

View File

@ -0,0 +1,144 @@
package com.annimon.everlastingsummer.drawables;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Canvas;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.SystemClock;
/**
* Плавный переход между несколькими изображениями.
* @author aNNiMON
*/
public class TransitionAnimationDrawable extends LayerDrawable {
private static final int TRANSITION_STARTING = 0;
private static final int TRANSITION_RUNNING = 1;
private static final int TRANSITION_NONE = 2;
private final int fullDuration;
private final int[] durations;
private final int lastIndex;
private int state;
private long startTime;
private int currentDuration;
private int fromIndex, toIndex;
public TransitionAnimationDrawable(int fullDuration, int[] durations, Drawable[] drawables) {
super(drawables);
this.fullDuration = fullDuration;
this.durations = durations;
state = TRANSITION_NONE;
lastIndex = durations.length - 1;
}
public int getFullDuration() {
return fullDuration;
}
public void startTransition() {
fromIndex = 0;
toIndex = 1;
startTransitionAnimation();
}
private void startTransitionAnimation() {
currentDuration = durations[toIndex];
state = TRANSITION_STARTING;
invalidateSelf();
}
@Override
public void draw(Canvas canvas) {
boolean done = false;
int alpha = 0;
switch (state) {
case TRANSITION_STARTING:
startTime = SystemClock.uptimeMillis();
state = TRANSITION_RUNNING;
break;
case TRANSITION_RUNNING:
if (currentDuration <= 0) {
done = true;
alpha = 255;
break;
}
float value = (SystemClock.uptimeMillis() - startTime) / (float) currentDuration;
if (value >= 1.0f) {
done = true;
value = 1.0f;
}
alpha = (int) (255 * value);
break;
default:
done = true;
}
if (done) {
// getDrawable(fromIndex).draw(canvas);
getDrawable(toIndex).draw(canvas);
if (state == TRANSITION_RUNNING) {
if (toIndex < lastIndex) {
// Новая итерация анимации
fromIndex++;
toIndex++;
startTransitionAnimation();
} else {
state = TRANSITION_NONE;
}
}
return;
}
// Рисуем подкладку
Drawable d = getDrawable(fromIndex);
d.draw(canvas);
// Рисуем наложенное изображение с прозрачностью
if (alpha > 0) {
d = getDrawable(toIndex);
d.setAlpha(alpha);
d.draw(canvas);
}
if (!done) invalidateSelf();
}
public static class Builder {
private static final Drawable NONE = new ColorDrawable();
private int fullDuration;
private final List<Integer> durations;
private final List<Drawable> drawables;
public Builder() {
fullDuration = 0;
this.durations = new ArrayList<Integer>();
this.drawables = new ArrayList<Drawable>();
}
public Builder add(int duration, Drawable drawable) {
fullDuration += duration;
durations.add(duration);
drawables.add(drawable == null ? NONE : drawable);
return this;
}
public TransitionAnimationDrawable build() {
final int size = durations.size();
final int[] durationsArray = new int[size];
final Drawable[] drawablesArray = new Drawable[size];
for (int i = 0; i < size; i++) {
durationsArray[i] = durations.get(i);
drawablesArray[i] = drawables.get(i);
}
return new TransitionAnimationDrawable(fullDuration, durationsArray, drawablesArray);
}
}
}