package eoc.studio.voicecard.animation;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.RotateAnimation;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;
public class FlipView extends RelativeLayout
{
private static final String TAG = "FlipView";
private static final long DEFAULT_FLIP_DURATION_MS = 400;
private static final float DEFAULT_ROTATE_BEGIN = -45f;
private static final float DEFAULT_ROTATE_END = 0;
private final Interpolator ACCELERATOR = new AccelerateInterpolator();
private final Interpolator DECELERATOR = new DecelerateInterpolator();
private boolean isFlipping = false;
private boolean isOpened = false;
private boolean isLockAfterOpened = false;
private boolean isTouchFlipEnabled = true;
private FrameLayout frontPage;
private FrameLayout backPage;
private FrameLayout innerPage;
private int pageWidth;
private int pageHeight;
private long flipDuration = DEFAULT_FLIP_DURATION_MS;
private float pivotY;
private final float[] ROTATE_FRONT_DEGREE1 = { DEFAULT_ROTATE_BEGIN, -90f };
private final float[] ROTATE_FRONT_DEGREE2 = { 90f, DEFAULT_ROTATE_END };
private final float[] ROTATE_BACK_DEGREE1 = { DEFAULT_ROTATE_END, 90f };
private final float[] ROTATE_BACK_DEGREE2 = { -90f, DEFAULT_ROTATE_BEGIN };
private void changeRotateDegree(float begin, float end)
{
ROTATE_FRONT_DEGREE1[0] = begin;
ROTATE_FRONT_DEGREE2[1] = end;
ROTATE_BACK_DEGREE1[0] = end;
ROTATE_BACK_DEGREE2[1] = begin;
}
private final OnTouchListener touchListener = new OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
if (isTouchFlipEnabled)
{
if (!(isLockAfterOpened && isOpened))
{
flip(frontPage, backPage);
}
}
return false;
}
};
private FlipListener mFlipListener = null;
public interface FlipListener
{
public void onOpened();
public void onClosed();
public void onStartOpening();
public void onStartClosing();
}
public FlipView(Context context, int width, int height, float rotationBegin, float rotationEnd,
float pivotY)
{
super(context);
changeRotateDegree(rotationBegin, rotationEnd);
this.pivotY = pivotY;
LayoutParams params = new LayoutParams(width, height);
setLayoutParams(params);
frontPage = new FrameLayout(context);
backPage = new FrameLayout(context);
innerPage = new FrameLayout(context);
pageWidth = width / 2;
pageHeight = height * 2 / 3;
Log.d(TAG, "page w,h " + pageWidth + ", " + pageHeight);
LayoutParams oddParams = new LayoutParams(pageWidth, pageHeight);
oddParams.addRule(CENTER_VERTICAL);
oddParams.addRule(ALIGN_PARENT_RIGHT);
oddParams.leftMargin = pageWidth;
frontPage.setLayoutParams(oddParams);
innerPage.setLayoutParams(oddParams);
LayoutParams evenParams = new LayoutParams(pageWidth, pageHeight);
evenParams.addRule(CENTER_VERTICAL);
evenParams.addRule(ALIGN_PARENT_LEFT);
backPage.setLayoutParams(evenParams);
backPage.setVisibility(INVISIBLE);
frontPage.setOnTouchListener(touchListener);
backPage.setOnTouchListener(touchListener);
frontPage.setPivotY(pivotY);
frontPage.setRotationY(rotationBegin);
backPage.setPivotY(pivotY);
backPage.setRotationY(rotationBegin);
addView(innerPage);
addView(backPage);
addView(frontPage);
}
public void setFrontPage(View v)
{
frontPage.removeAllViews();
frontPage.addView(v);
}
public View getFrontPage()
{
return frontPage.getChildAt(0);
}
public void setBackPage(View v)
{
backPage.removeAllViews();
backPage.addView(v);
}
public View getBackPage()
{
return backPage.getChildAt(0);
}
public void setInnerPage(View v)
{
innerPage.removeAllViews();
innerPage.addView(v);
innerPage.setTranslationX(-1);
}
public View getInnerPage()
{
return innerPage.getChildAt(0);
}
public void setDuration(long duration)
{
flipDuration = duration;
}
public long getDuration()
{
return flipDuration;
}
public boolean isOpened()
{
return isOpened;
}
public boolean isFlipping()
{
return isFlipping;
}
public void setLockAfterOpened(boolean lock)
{
isLockAfterOpened = lock;
}
public void setFlipListener(FlipListener listener)
{
mFlipListener = listener;
}
public void setTouchFlipEnabled(boolean enabled) {
isTouchFlipEnabled = enabled;
}
public void requestFlip()
{
if (!(isLockAfterOpened && isOpened))
{
flip(frontPage, backPage);
}
}
private void flip(final View front, final View back)
{
if (isFlipping) { return; }
isFlipping = true;
final View visiblePage, invisiblePage;
float[] animation1Degree, animation2Degree;
final boolean isOpening; // true: opening, false: closing
if (front.getVisibility() == VISIBLE)
{
isOpening = true;
animation1Degree = ROTATE_FRONT_DEGREE1;
animation2Degree = ROTATE_FRONT_DEGREE2;
visiblePage = front;
invisiblePage = back;
visiblePage.setPivotX(0);
invisiblePage.setPivotX(pageWidth);
}
else
{
isOpening = false;
animation1Degree = ROTATE_BACK_DEGREE1;
animation2Degree = ROTATE_BACK_DEGREE2;
visiblePage = back;
invisiblePage = front;
visiblePage.setPivotX(pageWidth);
invisiblePage.setPivotX(0);
}
visiblePage.setPivotY(pivotY);
invisiblePage.setPivotY(pivotY);
ObjectAnimator animation1 = ObjectAnimator.ofFloat(visiblePage, "rotationY",
animation1Degree);
animation1.setDuration(flipDuration);
animation1.setInterpolator(ACCELERATOR);
final ObjectAnimator animation2 = ObjectAnimator.ofFloat(invisiblePage, "rotationY",
animation2Degree);
animation2.setDuration(flipDuration);
animation2.setInterpolator(DECELERATOR);
animation1.addListener(new AnimatorListenerAdapter()
{
@Override
public void onAnimationEnd(Animator anim)
{
visiblePage.setVisibility(View.INVISIBLE);
invisiblePage.setVisibility(View.VISIBLE);
animation2.start();
}
});
animation2.addListener(new AnimatorListenerAdapter()
{
@Override
public void onAnimationEnd(Animator anim)
{
isFlipping = false;
isOpened = isOpening;
if (mFlipListener != null)
{
if (isOpened)
{
mFlipListener.onOpened();
}
else
{
mFlipListener.onClosed();
}
}
}
});
animation1.start();
if (mFlipListener != null)
{
if (isOpening)
{
mFlipListener.onStartOpening();
}
else
{
mFlipListener.onStartClosing();
}
}
}
}