package oxim.digital.rxanim;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import java.util.concurrent.TimeUnit;
import rx.Completable;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action0;
import static oxim.digital.rxanim.RxAnimationBuilder.animate;
public final class RxAnimations {
private static final float OPAQUE = 1.0f;
private static final float TRANSPARENT = 0.0f;
private static final int IMMEDIATE = 0;
public static Completable animateTogether(final Completable... completables) {
return Completable.merge(completables);
}
public static Completable hide(final View view) {
return animate(view, IMMEDIATE).fadeOut().schedule();
}
public static Completable hide(final View... views) {
return Observable.from(views)
.flatMap(view -> hide(view).toObservable())
.toCompletable();
}
public static Completable hideViewGroupChildren(final ViewGroup viewGroup) {
return Completable.fromAction(() -> hideViewGroup(viewGroup));
}
public static Completable hideViewGroupChildren(final ViewGroup... viewGroups) {
return Observable.from(viewGroups)
.flatMap(viewGroup -> hideViewGroupChildren(viewGroup).toObservable())
.toCompletable();
}
private static void hideViewGroup(final ViewGroup viewGroup) {
for (int i = 0, childCount = viewGroup.getChildCount(); i < childCount; i++) {
final View child = viewGroup.getChildAt(i);
if (child instanceof ViewGroup) {
hideViewGroup((ViewGroup) child);
} else {
child.setAlpha(0f);
}
}
}
public static Completable show(final View view) {
return animate(view, IMMEDIATE).fadeIn().schedule();
}
public static Completable fadeIn(final View view) {
return animate(view).fadeIn()
.onAnimationCancel(aView -> aView.setAlpha(OPAQUE))
.schedule();
}
public static Completable fadeIn(final View view, final int duration) {
return animate(view, new DecelerateInterpolator())
.duration(duration)
.fadeIn()
.onAnimationCancel(aView -> aView.setAlpha(OPAQUE))
.schedule();
}
public static Completable fadeIn(final View view, final int duration, final int delay) {
return animate(view, duration, delay)
.interpolator(new DecelerateInterpolator())
.fadeIn()
.onAnimationCancel(aView -> aView.setAlpha(OPAQUE))
.schedule();
}
public static Completable fadeInWithDelay(final int delay, final int duration, final View... views) {
return Observable.range(0, views.length)
.flatMap(i -> animate(views[i], new LinearInterpolator())
.duration(duration)
.delay(i * delay)
.fadeIn()
.onAnimationCancel(aView -> aView.setAlpha(OPAQUE))
.schedule().toObservable())
.toCompletable();
}
public static Completable slideHorizontal(final View view, final int duration, final int xOffset) {
final float endingX = view.getX() + xOffset;
return animate(view, new AccelerateDecelerateInterpolator())
.duration(duration)
.translateBy(xOffset, 0)
.onAnimationCancel(v -> v.setX(endingX))
.schedule(false);
}
public static Completable slideVertical(final View view, final int duration, final int yOffset) {
final float endingY = view.getY() + yOffset;
return animate(view, new AccelerateDecelerateInterpolator())
.duration(duration)
.translateBy(0, yOffset)
.onAnimationCancel(v -> v.setY(endingY))
.schedule(false);
}
public static Completable enter(final View view, final int xOffset, final int yOffset) {
final float startingX = view.getX();
final float startingY = view.getY();
return animate(view, new DecelerateInterpolator())
.fadeIn()
.translateBy(xOffset, yOffset)
.onAnimationCancel(aView -> set(aView, startingX, startingY, OPAQUE))
.schedule();
}
public static Completable enter(final View view, final int delay, final int xOffset, final int yOffset) {
final float startingX = view.getX();
final float startingY = view.getY();
return animate(view, new DecelerateInterpolator())
.delay(delay)
.fadeIn()
.translateBy(xOffset, yOffset)
.onAnimationCancel(aView -> set(aView, startingX, startingY, OPAQUE))
.schedule();
}
public static Completable enter(final View view, final int duration, final int xOffset, final int yOffset, final int delay) {
final float startingX = view.getX();
final float startingY = view.getY();
return animate(view, duration, delay)
.interpolator(new DecelerateInterpolator())
.fadeIn()
.translateBy(xOffset, yOffset)
.onAnimationCancel(aView -> set(aView, startingX, startingY, OPAQUE))
.schedule();
}
public static Completable enterTogether(final int delay, final int xOffset, final View... views) {
return Observable.from(views)
.flatMap(view -> enter(view, xOffset, 0).toObservable())
.toCompletable();
}
public static Completable enterViewsWithDelay(final int delay, final int duration, final int xOffset, final View... views) {
return enterViewsWithDelay(0, delay, duration, xOffset, views);
}
public static Completable enterViewsWithDelay(final int initialDelay, final int delay, final int duration, final int xOffset, final View... views) {
return Observable.range(0, views.length)
.flatMap(i -> enter(views[i], duration, xOffset, 0, i * delay + initialDelay).toObservable())
.toCompletable();
}
public static Completable enterWithRotation(final View view, final int duration, final int xOffset, final int yOffset, final int delay, final int rotation) {
final float startingX = view.getX();
final float startingY = view.getY();
final float startRotation = view.getRotation();
return animate(view, duration, delay)
.fadeIn()
.counterRotateBy(rotation)
.translateBy(xOffset, yOffset)
.onAnimationCancel(aView -> set(aView, startingX, startingY, OPAQUE, startRotation))
.schedule();
}
public static Completable leave(final View view, final int xOffset, final int yOffset) {
final float startingX = view.getX();
final float startingY = view.getY();
return animate(view, new AccelerateInterpolator())
.fadeOut()
.translateBy(xOffset, yOffset)
.onAnimationCancel(aView -> set(aView, startingX, startingY, TRANSPARENT))
.schedule(false);
}
public static Completable fadeOut(final View view) {
return animate(view, new AccelerateInterpolator())
.fadeOut()
.onAnimationCancel(aView -> aView.setAlpha(TRANSPARENT))
.schedule();
}
public static Completable fadeOut(final View view, final int duration) {
return animate(view, new AccelerateInterpolator())
.duration(duration)
.fadeOut()
.onAnimationCancel(aView -> aView.setAlpha(TRANSPARENT))
.schedule();
}
public static Completable fadeOut(final View view, final int duration, final int delay) {
return animate(view, duration, delay)
.interpolator(new AccelerateInterpolator())
.fadeOut()
.onAnimationCancel(aView -> aView.setAlpha(TRANSPARENT))
.schedule();
}
public static Completable doAfterDelay(final int delay, final Action0 action) {
return Completable.timer(delay, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.concatWith(Completable.fromAction(action));
}
public static void set(final View view, final float x, final float y, final float alpha) {
view.setAlpha(alpha);
view.setX(x);
view.setY(y);
}
public static void set(final View view, final float x, final float y, final float alpha, final float rotation) {
set(view, x, y, alpha);
view.setRotation(rotation);
}
}