package com.cheng.animationstudy.customview.viewnatruetransition;
import android.animation.PointFEvaluator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class CustomAnimator extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener {
private final int ANIMATION_DURATION = 300;
private ViewGroup mMainContainer;
private View mFocusedView;
private View mFocusedViewContainer;
private List<View> mFadedOutToBottomViews;
private List<View> mSlideToTop;
private View mStickyTo;
private ViewGroup mEditModeViewGroup;
private final Rect mTmpRect;
private boolean mIsRevert;
private int mEditModeHalfHeight;
public CustomAnimator() {
super();
mTmpRect = new Rect();
mIsRevert = false;
mFadedOutToBottomViews = new ArrayList<View>();
mSlideToTop = new ArrayList<View>();
setInterpolator(new DecelerateInterpolator());
setDuration(ANIMATION_DURATION);
addUpdateListener(this);
}
public void setAnimatorViews(ViewGroup mainContainer, View focusedView, View focusedViewContainer, List<View> fadedOutToBottomViews, View stickyTo, ViewGroup editModeView, List<View> slideToTop) {
if (mainContainer == null) throw new NullPointerException();
if (focusedView == null) throw new NullPointerException();
if (focusedViewContainer == null) throw new NullPointerException();
if (editModeView == null) throw new NullPointerException();
mMainContainer = mainContainer;
mFocusedView = focusedView;
mFocusedViewContainer = focusedViewContainer;
mFadedOutToBottomViews.clear();
if (fadedOutToBottomViews != null) {
mFadedOutToBottomViews.addAll(fadedOutToBottomViews);
}
mStickyTo = stickyTo;
mEditModeViewGroup = editModeView;
mSlideToTop.clear();
if (slideToTop != null) {
mSlideToTop.addAll(slideToTop);
}
removeAllListeners();
addListener(new LayerEnablingAnimatorListener(focusedView));
for (View v : mFadedOutToBottomViews) {
addListener(new LayerEnablingAnimatorListener(v));
}
for (View v : mSlideToTop) {
addListener(new LayerEnablingAnimatorListener(v));
}
addListener(new LayerEnablingAnimatorListener(editModeView));
}
public void setEditModeHalfHeight(int editModeHalfHeight) {
mEditModeHalfHeight = editModeHalfHeight;
}
private Positions getPositionsStart() {
// focusOn
float focusY = mFocusedViewContainer.getY();
// slideToTop
int slideToTopSize = mSlideToTop.size();
float[] slideToTopY = new float[slideToTopSize];
for (int i = 0; i < slideToTopSize; i++) {
slideToTopY[i] = mSlideToTop.get(i).getY();
}
// fadeToBottom
int fadeToBottomSize = mFadedOutToBottomViews.size();
float[] nextContainersY = new float[fadeToBottomSize];
for (int i = 0; i < fadeToBottomSize; i++) {
nextContainersY[i] = mFadedOutToBottomViews.get(i).getY();
}
float nextContainersAlpha = 1;
// stickToY
float stickToY = mStickyTo==null ? 0 : mStickyTo.getY();
// fadeInToTop
float editY = mEditModeViewGroup.getY();
float editAlpha = 0f;
return new Positions(focusY, nextContainersY, nextContainersAlpha, stickToY, editY, editAlpha, slideToTopY);
}
private Positions getPositionsEnd() {
// focusOn
mFocusedView.getDrawingRect(mTmpRect);
mMainContainer.offsetDescendantRectToMyCoords(mFocusedView, mTmpRect);
float focusY = mFocusedViewContainer.getY() - mTmpRect.top;
// slideToTop
float[] slideToTopY = new float[mSlideToTop.size()];
for (int i = 0; i < mSlideToTop.size(); i++) {
slideToTopY[i] = mSlideToTop.get(i).getY() - mTmpRect.top;
}
// fadeToBottom
float[] nextContainersY = new float[mFadedOutToBottomViews.size()];
for (int i = 0; i < mFadedOutToBottomViews.size(); i++) {
nextContainersY[i] = mFadedOutToBottomViews.get(i).getY() + mEditModeHalfHeight;
}
float nextContainersAlpha = 0;
// stickyTo
float stickToY = 0;
if (mStickyTo != null) {
mStickyTo.getDrawingRect(mTmpRect);
mMainContainer.offsetDescendantRectToMyCoords(mStickyTo, mTmpRect);
stickToY = mStickyTo.getY() + (mStickyTo.getHeight() - mTmpRect.top);
}
// fadeInToTop
float editY = 0;
float editAlpha = 1f;
return new Positions(focusY, nextContainersY, nextContainersAlpha, stickToY, editY, editAlpha, slideToTopY);
}
@SuppressLint("NewApi")
public void prepareAnimation() {
mIsRevert = false;
setObjectValues(getPositionsStart(), getPositionsEnd());
setEvaluator(new PositionTypeEvaluator());
}
private Positions getRevertPositionsStart() {
// focusOn
float focusY = mFocusedViewContainer.getY();
// slideToTop
float[] slideToTopY = new float[mSlideToTop.size()];
for (int i = 0; i < mSlideToTop.size(); i++) {
slideToTopY[i] = mSlideToTop.get(i).getY();
}
// fadeToBottom
float[] nextContainersY = new float[mFadedOutToBottomViews.size()];
for (int i = 0; i < mFadedOutToBottomViews.size(); i++) {
nextContainersY[i] = mFadedOutToBottomViews.get(i).getY();
}
float nextContainersAlpha = 0;
// stickyTo
float stickToY = mStickyTo == null ? 0 : mStickyTo.getY();
// fadeInToTop
float editY = mEditModeViewGroup.getY();
float editAlpha = 1f;
return new Positions(focusY, nextContainersY, nextContainersAlpha, stickToY, editY, editAlpha, slideToTopY);
}
private Positions getRevertPositionsEnd() {
// focusOn
mFocusedView.getDrawingRect(mTmpRect);
mMainContainer.offsetDescendantRectToMyCoords(mFocusedView, mTmpRect);
float focusY = mFocusedViewContainer.getY() + mTmpRect.top;
// slideToTop
float[] slideToTopY = new float[mSlideToTop.size()];
for (int i = 0; i < mSlideToTop.size(); i++) {
slideToTopY[i] = mSlideToTop.get(i).getY() + mTmpRect.top;
}
// fadeToBottom
float[] nextContainersY = new float[mFadedOutToBottomViews.size()];
for (int i = 0; i < mFadedOutToBottomViews.size(); i++) {
nextContainersY[i] = mFadedOutToBottomViews.get(i).getY() - mEditModeHalfHeight;
}
float nextContainersAlpha = 1;
// stickyTo
float stickToY = 0;
if (mStickyTo != null) {
mStickyTo.getDrawingRect(mTmpRect);
mMainContainer.offsetDescendantRectToMyCoords(mStickyTo, mTmpRect);
stickToY = mStickyTo.getY() - (mStickyTo.getHeight() - mTmpRect.top);
}
// fadeInToTop
float editY = mEditModeHalfHeight;
float editAlpha = 0f;
return new Positions(focusY, nextContainersY, nextContainersAlpha, stickToY, editY, editAlpha, slideToTopY);
}
public void prepareRevert() {
mIsRevert = true;
setObjectValues(getRevertPositionsStart(), getRevertPositionsEnd());
setEvaluator(new PositionTypeEvaluator());
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Positions currentPos = (Positions) animation.getAnimatedValue();
if (!mIsRevert) {
for (int i = 0; i < mSlideToTop.size(); i++) {
mSlideToTop.get(i).setY(currentPos.getSlideToTop()[i]);
}
mFocusedViewContainer.setY(currentPos.getFocusY());
for (int i = 0; i < mFadedOutToBottomViews.size(); i++) {
mFadedOutToBottomViews.get(i).setY(currentPos.getNextContainersY()[i]);
mFadedOutToBottomViews.get(i).setAlpha(currentPos.getNextContainersAlpha());
}
if (mStickyTo != null)
mStickyTo.setY(currentPos.getStickToY());
mEditModeViewGroup.setY(currentPos.getEditY());
mEditModeViewGroup.setAlpha(currentPos.getEditAlpha());
mEditModeViewGroup.setVisibility(View.VISIBLE);
} else {
mEditModeViewGroup.setY(currentPos.getEditY());
mEditModeViewGroup.setAlpha(currentPos.getEditAlpha());
if (mStickyTo != null)
mStickyTo.setY(currentPos.getStickToY());
for (int i = 0; i < mFadedOutToBottomViews.size(); i++) {
mFadedOutToBottomViews.get(i).setY(currentPos.getNextContainersY()[i]);
mFadedOutToBottomViews.get(i).setAlpha(currentPos.getNextContainersAlpha());
}
mFocusedViewContainer.setY(currentPos.getFocusY());
for (int i = 0; i < mSlideToTop.size(); i++) {
mSlideToTop.get(i).setY(currentPos.getSlideToTop()[i]);
}
}
}
}