package com.example.administrator.cookman.ui.component.fab_transformation.animation;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import com.example.administrator.cookman.ui.component.fab_transformation.FabTransformation;
public abstract class FabAnimator {
static final float FAB_SCALE = 1.2f;
static final Interpolator REVEAL_INTERPOLATOR = new DecelerateInterpolator();
static final Interpolator FAB_INTERPOLATOR = new AccelerateInterpolator();
static final Interpolator OVERLAY_INTERPOLATOR = new AccelerateDecelerateInterpolator();
private long fabAnimationDuration;
private long revealAnimationDuration;
abstract void fabMoveIn(View fab, View transformView, FabAnimationCallback callback);
abstract void fabMoveOut(View fab, View transformView, FabAnimationCallback callback);
abstract void revealOn(View fab, View transformView, RevealCallback callback);
abstract void revealOff(View fab, View transformView, RevealCallback callback);
abstract void showOverlay(final View overlay);
abstract void hideOverlay(final View overlay);
private void calculateDuration(View fab, View transformView, long duration) {
int fabTranslationX = getTranslationX(fab, transformView);
int fabTranslationY = getTranslationY(fab, transformView);
float maxFabTranslation = Math.max(Math.abs(fabTranslationX), Math.abs(fabTranslationY)) * 1.5f;
float maxTransformView = Math.max(Math.abs(transformView.getWidth()), Math.abs(transformView.getHeight()));
this.fabAnimationDuration = (long) (duration * (maxFabTranslation / (maxFabTranslation + maxTransformView)));
this.revealAnimationDuration = (long) (duration * (maxTransformView / (maxFabTranslation + maxTransformView)));
}
long getFabAnimationDuration() {
return fabAnimationDuration;
}
long getRevealAnimationDuration() {
return revealAnimationDuration;
}
public void transformTo(final View fab, final View transformView, long duration, final View overlay,
final FabTransformation.OnTransformListener listener) {
calculateDuration(fab, transformView, duration);
fabMoveIn(fab, transformView, new FabAnimationCallback() {
@Override
public void onAnimationStart() {
if (overlay != null) showOverlay(overlay);
if (listener != null) listener.onStartTransform();
}
@Override
public void onAnimationEnd() {
revealOn(fab, transformView, new RevealCallback() {
@Override
public void onRevealStart() {
fab.setVisibility(View.INVISIBLE);
}
@Override
public void onRevealEnd() {
if (listener != null) listener.onEndTransform();
}
});
}
@Override
public void onAnimationCancel() {
//
}
@Override
public void onAnimationRepeat() {
//
}
});
}
public void transformOut(final View fab, final View transformView, long duration, final View overlay,
final FabTransformation.OnTransformListener listener) {
calculateDuration(fab, transformView, duration);
if (overlay != null) hideOverlay(overlay);
revealOff(fab, transformView, new RevealCallback() {
@Override
public void onRevealStart() {
if (listener != null) listener.onStartTransform();
}
@Override
public void onRevealEnd() {
fabMoveOut(fab, transformView, new FabAnimationCallback() {
@Override
public void onAnimationStart() {
fab.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd() {
if (listener != null) listener.onEndTransform();
}
@Override
public void onAnimationCancel() {
//
}
@Override
public void onAnimationRepeat() {
//
}
});
}
});
}
int getCenterX(View view) {
return view.getWidth() / 2 + view.getLeft();
}
int getCenterY(View view) {
return view.getHeight() / 2 + view.getTop();
}
int getTranslationX(View fab, View transformView) {
int fabX = ViewUtil.getRelativeLeft(fab) + fab.getWidth() / 2;
int transformViewX = ViewUtil.getRelativeLeft(transformView) + transformView.getWidth() / 2;
return transformViewX - fabX;
}
int getTranslationY(View fab, View transformView) {
int fabY = ViewUtil.getRelativeTop(fab) + fab.getHeight() / 2;
int transformViewY = ViewUtil.getRelativeTop(transformView) + transformView.getHeight() / 2;
return transformViewY - fabY;
}
interface RevealCallback {
void onRevealStart();
void onRevealEnd();
}
interface FabAnimationCallback {
void onAnimationStart();
void onAnimationEnd();
void onAnimationCancel();
void onAnimationRepeat();
}
}