package com.owen.tvrecyclerview.example.bridge;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
/**
* 自定义Anim Bridge DEMO. <br>
* 如果你想实现自己不同风格的东西, <br>
* 继承 BaseAnimBridge 重写几个函数吧. <br>
* 后续将推出更多风格的 Anim Bridge. <br>
* 使用方法 MainUpView.setAnimBridge(new OpenEffectBridge()); <br>
* @author hailongqiu 356752238@qq.com
*
*/
public class OpenEffectBridge extends BaseEffectBridgeWrapper {
private static final int DEFAULT_TRAN_DUR_ANIM = 300;
private int mTranDurAnimTime = DEFAULT_TRAN_DUR_ANIM;
private AnimatorSet mCurrentAnimatorSet;
private boolean isInDraw = false;
private boolean mIsHide = false;
private boolean mAnimEnabled = true;
private boolean isDrawUpRect = true;
private View mFocusView;
private NewAnimatorListener mNewAnimatorListener;
@Override
public void onInitBridge(MainUpView view) {
super.onInitBridge(view);
/**
* 防止边框第一次出现,<br>
* 从另一个地方飘过来的问题.<br>
*/
view.setVisibility(View.INVISIBLE);
}
/**
* 设置是否移动边框在最下层(绘制的层次). <br>
* true : 移动边框在最上层. 反之否. <br>
*/
public void setDrawUpRectEnabled(boolean isDrawUpRect) {
this.isDrawUpRect = isDrawUpRect;
getMainUpView().invalidate();
}
/**
* 控件动画时间.
*/
public void setTranDurAnimTime(int time) {
mTranDurAnimTime = time;
}
public int getTranDurAnimTime() {
return this.mTranDurAnimTime;
}
/**
* 让动画失效.
*/
public void setAnimEnabled(boolean animEnabled) {
this.mAnimEnabled = animEnabled;
}
public boolean isAnimEnabled() {
return this.mAnimEnabled;
}
/**
* 隐藏移动的边框.
*/
public void setVisibleWidget(boolean isHide) {
this.mIsHide = isHide;
getMainUpView().setVisibility(mIsHide ? View.INVISIBLE : View.VISIBLE);
}
public boolean isVisibleWidget() {
return this.mIsHide;
}
public interface NewAnimatorListener {
public void onAnimationStart(OpenEffectBridge bridge, View view, Animator animation);
public void onAnimationEnd(OpenEffectBridge bridge, View view, Animator animation);
}
/**
* 监听动画的回调.
*/
public void setOnAnimatorListener(NewAnimatorListener newAnimatorListener) {
mNewAnimatorListener = newAnimatorListener;
}
public NewAnimatorListener getNewAnimatorListener() {
return mNewAnimatorListener;
}
@Override
public void onOldFocusView(View oldFocusView, float scaleX, float scaleY) {
if (!mAnimEnabled)
return;
if (oldFocusView != null) {
oldFocusView.animate().scaleX(scaleX).scaleY(scaleY).setDuration(mTranDurAnimTime).start();
}
}
@Override
public void onFocusView(View focusView, float scaleX, float scaleY) {
mFocusView = focusView;
if (!mAnimEnabled)
return;
if (focusView != null) {
focusView.animate().scaleX(scaleX).scaleY(scaleY).setDuration(mTranDurAnimTime).start(); // 放大焦点VIEW的动画.
runTranslateAnimation(focusView, scaleX, scaleY); // 移动边框的动画。
}
}
private float mScaleX = 0;
private float mScaleY = 0;
/**
* 移动边框的动画处理函数.
*/
@Override
public void flyWhiteBorder(final View focusView, View moveView, float scaleX, float scaleY) {
// 用于修复5.0边框错位问题.
this.mScaleX = mScaleX;
this.mScaleY = mScaleY;
int newWidth = 0;
int newHeight = 0;
int oldWidth = 0;
int oldHeight = 0;
int newX = 0;
int newY = 0;
if (focusView != null) {
newWidth = (int) (focusView.getMeasuredWidth() * scaleX);
newHeight = (int) (focusView.getMeasuredHeight() * scaleY);
oldWidth = moveView.getMeasuredWidth();
oldHeight = moveView.getMeasuredHeight();
Rect fromRect = findLocationWithView(moveView); // 获取moveView在屏幕上的位置.
Rect toRect = findLocationWithView(focusView); // 获取focusView在屏幕上的位置.
int x = toRect.left - fromRect.left;
int y = toRect.top - fromRect.top;
newX = x - Math.abs(focusView.getMeasuredWidth() - newWidth) / 2;
newY = y - Math.abs(focusView.getMeasuredHeight() - newHeight) / 2;
}
// 取消之前的动画.
if (mCurrentAnimatorSet != null)
mCurrentAnimatorSet.cancel();
ObjectAnimator transAnimatorX = ObjectAnimator.ofFloat(moveView, "translationX", newX);
ObjectAnimator transAnimatorY = ObjectAnimator.ofFloat(moveView, "translationY", newY);
// BUG,因为缩放会造成图片失真(拉伸).
// hailong.qiu 2016.02.26 修复 :)
ObjectAnimator scaleXAnimator = ObjectAnimator.ofInt(new ScaleView(moveView), "width", oldWidth,
(int) newWidth);
ObjectAnimator scaleYAnimator = ObjectAnimator.ofInt(new ScaleView(moveView), "height", oldHeight,
(int) newHeight);
//
AnimatorSet mAnimatorSet = new AnimatorSet();
mAnimatorSet.playTogether(transAnimatorX, transAnimatorY, scaleXAnimator, scaleYAnimator);
mAnimatorSet.setInterpolator(new DecelerateInterpolator(1));
mAnimatorSet.setDuration(mTranDurAnimTime);
mAnimatorSet.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
if (!isDrawUpRect)
isInDraw = false;
if (mIsHide) {
getMainUpView().setVisibility(View.INVISIBLE);
}
if (mNewAnimatorListener != null)
mNewAnimatorListener.onAnimationStart(OpenEffectBridge.this, focusView, animation);
}
@Override
public void onAnimationRepeat(Animator animation) {
if (!isDrawUpRect)
isInDraw = false;
}
@Override
public void onAnimationEnd(Animator animation) {
if (!isDrawUpRect)
isInDraw = true;
getMainUpView().setVisibility(mIsHide ? View.INVISIBLE : View.VISIBLE);
if (mNewAnimatorListener != null)
mNewAnimatorListener.onAnimationEnd(OpenEffectBridge.this, focusView, animation);
// XF add(先锋TV开发(404780246)修复)
// BUG:5.0系统边框错位.
// if (Utils.getSDKVersion() >= 21) {
// int newWidth = (int) (focusView.getMeasuredWidth() *
// mScaleX);
// int newHeight = (int) (focusView.getMeasuredHeight() *
// mScaleY);
// getMainUpView().getLayoutParams().width = newWidth;
// getMainUpView().getLayoutParams().height = newHeight;
// getMainUpView().requestLayout();
// }
}
@Override
public void onAnimationCancel(Animator animation) {
if (!isDrawUpRect)
isInDraw = false;
}
});
mAnimatorSet.start();
mCurrentAnimatorSet = mAnimatorSet;
}
/**
* 重寫了繪製的函數.
*/
@Override
public boolean onDrawMainUpView(Canvas canvas) {
canvas.save();
if (!isDrawUpRect) {
// 绘制阴影.
onDrawShadow(canvas);
// 绘制最上层的边框.
onDrawUpRect(canvas);
}
// 绘制焦点子控件.
if (mFocusView != null && (!isDrawUpRect && isInDraw)) {
onDrawFocusView(canvas);
}
//
if (isDrawUpRect) {
// 绘制阴影.
onDrawShadow(canvas);
// 绘制最上层的边框.
onDrawUpRect(canvas);
}
canvas.restore();
return true;
}
public void onDrawFocusView(Canvas canvas) {
View view = mFocusView;
canvas.save();
float scaleX = (float) (getMainUpView().getWidth()) / (float) view.getWidth();
float scaleY = (float) (getMainUpView().getHeight()) / (float) view.getHeight();
canvas.scale(scaleX, scaleY);
view.draw(canvas);
canvas.restore();
}
}