核心类:
package immortalz.me.library;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import java.util.HashMap;
import immortalz.me.library.bean.InfoBean;
import immortalz.me.library.method.InflateShowMethod;
import immortalz.me.library.method.NoneShowMethod;
import immortalz.me.library.method.ShowMethod;
import immortalz.me.library.view.CirleAnimView;
/**
* Created by Mr_immortalZ on 2016/10/18.
* email : mr_immortalz@qq.com
*/
public class TransitionsHeleper {
private static TransitionsHeleper INSTANCE;
private static HashMap<String, InfoBean> staticMap = new HashMap<>();
private static ShowMethod showMethod = new NoneShowMethod();
private TransitionsHeleper() {
}
public static TransitionsHeleper getInstance() {
if (INSTANCE == null) {
synchronized (TransitionsHeleper.class) {
if (INSTANCE == null) {
INSTANCE = new TransitionsHeleper();
}
}
}
return INSTANCE;
}
public static void startAcitivty(final Activity activity, final Class<?> cls, final View view) {
startAcitivty(activity, cls, view, 0);
}
public static void startAcitivty(final Activity activity, final Class<?> cls, final View view, final Integer imgId) {
final Intent intent = new Intent(activity, cls);
final InfoBean bean = new InfoBean();
view.post(new Runnable() {
@Override
public void run() {
//get statusBar height
view.getWindowVisibleDisplayFrame(bean.originRect);
bean.statusBarHeight = bean.originRect.top;
//get Origin View's rect
view.getGlobalVisibleRect(bean.originRect);
bean.originWidth = bean.originRect.right - bean.originRect.left;
bean.originHeight = bean.originRect.bottom - bean.originRect.top;
if (imgId == 0) {
bean.bitmap = createBitmap(view, bean.originWidth, bean.originHeight);
} else {
bean.setImgId(imgId);
}
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
staticMap.put(cls.getName(), bean);
activity.startActivity(intent);
activity.overridePendingTransition(0,0);
}
});
}
public static void startAcitivty(final Activity activity, final Class<?> cls, final View view, final String imgUrl) {
final Intent intent = new Intent(activity, cls);
final InfoBean bean = new InfoBean();
view.post(new Runnable() {
@Override
public void run() {
//get statusBar height
view.getWindowVisibleDisplayFrame(bean.originRect);
bean.statusBarHeight = bean.originRect.top;
//get Origin View's rect
view.getGlobalVisibleRect(bean.originRect);
bean.originWidth = bean.originRect.right - bean.originRect.left;
bean.originHeight = bean.originRect.bottom - bean.originRect.top;
if (TextUtils.isEmpty(imgUrl)) {
bean.bitmap = createBitmap(view, bean.originWidth, bean.originHeight);
} else {
bean.setImgUrl(imgUrl);
}
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
staticMap.put(cls.getName(), bean);
activity.startActivity(intent);
activity.overridePendingTransition(0, 0);
}
});
}
public void show(final Activity activity, final ImageView targetView) {
final InfoBean bean = staticMap.get(activity.getClass().getName());
if (bean == null) {
return;
}
final ViewGroup parent = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT);
//if TranslucentStatus is true , statusBarHeight = 0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (activity.getWindow().getStatusBarColor() == 0 ||
(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS & activity.getWindow().getAttributes().flags)
== WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) {
bean.statusBarHeight = 0;
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if ((WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS & activity.getWindow().getAttributes().flags)
== WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) {
bean.statusBarHeight = 0;
}
}
parent.post(new Runnable() {
@Override
public void run() {
bean.windowWidth = parent.getWidth();
bean.windowHeight = parent.getHeight();
bean.titleHeight = parent.getTop();
final CirleAnimView cirleAnimView;
if (showMethod instanceof InflateShowMethod) {
cirleAnimView = new CirleAnimView(activity,
createBitmap(((InflateShowMethod) showMethod).inflateView, bean.windowWidth, bean.windowHeight));
} else {
cirleAnimView = new CirleAnimView(activity);
}
final RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
parent.addView(cirleAnimView, params);
if (targetView != null) {
//get Target View's position
targetView.getGlobalVisibleRect(bean.targetRect);
bean.targetWidth = bean.targetRect.right - bean.targetRect.left;
bean.targetHeight = bean.targetRect.bottom - bean.targetRect.top;
bean.translationX = bean.originRect.left + bean.originWidth / 2 - bean.targetRect.left - bean.targetWidth / 2;
bean.translationY = bean.originRect.top + bean.originHeight / 2 - bean.targetRect.top - bean.targetHeight / 2;
} else {
bean.targetRect.left = bean.originRect.left;
bean.targetRect.top = bean.originRect.top;
bean.targetWidth = bean.originWidth;
bean.targetHeight = bean.originHeight;
bean.translationX = 0;
bean.translationY = 0;
}
//create a temp ImageView to replace origin view
final ImageView ivTemp = new ImageView(activity);
if (bean.bitmap != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
ivTemp.setImageDrawable(new BitmapDrawable(bean.bitmap));
} else {
ivTemp.setBackgroundDrawable(new BitmapDrawable(bean.bitmap));
}
}
RelativeLayout.LayoutParams ivTempParams = new RelativeLayout.LayoutParams(bean.targetWidth,
bean.targetHeight);
ivTempParams.setMargins(bean.originRect.left - (bean.targetWidth / 2 - bean.originWidth / 2)
, bean.originRect.top - (parent.getTop() + bean.statusBarHeight) - (bean.targetHeight / 2 - bean.originHeight / 2), 0, 0);
cirleAnimView.addView(ivTemp, ivTempParams);
ivTemp.setScaleX((float) bean.originHeight / bean.targetHeight);
ivTemp.setScaleY((float) bean.originWidth / bean.targetWidth);
showMethod.translate(bean, cirleAnimView, ivTemp);
showMethod.loadCopyView(bean, ivTemp);
showMethod.set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
cirleAnimView.startCircleAnim(bean);
showMethod.loadTargetView(bean, targetView);
}
});
}
});
}
public TransitionsHeleper setShowMethod(ShowMethod showMethod) {
this.showMethod = showMethod;
return this;
}
public static void unBind(Activity activity) {
if (staticMap.get(activity.getClass().getName()) != null) {
InfoBean bean = staticMap.get(activity.getClass().getName());
if (bean.bitmap != null) {
bean.bitmap = null;
}
staticMap.remove(activity.getClass().getName());
}
}
private static Bitmap createBitmap(View view, int width, int height) {
view.setDrawingCacheEnabled(true);
view.measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY));
view.buildDrawingCache();
return view.getDrawingCache();
}
}
package immortalz.me.library.method;
import android.animation.AnimatorSet;
import android.view.View;
import android.widget.ImageView;
import immortalz.me.library.bean.InfoBean;
import immortalz.me.library.view.RenderView;
/**
* Created by Mr_immortalZ on 2016/10/24.
* email : mr_immortalz@qq.com
*/
public abstract class ShowMethod {
public AnimatorSet set = new AnimatorSet();
protected int duration = 500;
public abstract void translate(InfoBean bean, RenderView parent, View child);
/**
* load copyView which just a temp view.
* the copyView is show when it's translating.
*/
public abstract void loadCopyView(InfoBean bean,ImageView copyView);
/**
* load targetView
*/
public void loadTargetView(InfoBean bean, ImageView targetView){
}
}
package immortalz.me.library.method;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import immortalz.me.library.bean.InfoBean;
import immortalz.me.library.view.RenderView;
/**
* Created by Mr_immortalZ on 2016/10/24.
* email : mr_immortalz@qq.com
*/
public abstract class InflateShowMethod extends ShowMethod {
public View inflateView;
public InflateShowMethod(Activity activity, int layoutId) {
this.inflateView = LayoutInflater.from(activity).inflate(layoutId, null);
}
@Override
public void translate(InfoBean bean, RenderView parent, View child) {
set.playTogether(
ObjectAnimator.ofFloat(child, "translationX", 0, -bean.translationX),
ObjectAnimator.ofFloat(child, "translationY", 0, -bean.translationY),
ObjectAnimator.ofFloat(child, "scaleX", 1),
ObjectAnimator.ofFloat(child, "scaleY", 1)
);
set.setInterpolator(new AccelerateInterpolator());
set.setDuration(duration).start();
}
}
package immortalz.me.library.method;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import immortalz.me.library.R;
import immortalz.me.library.bean.InfoBean;
import immortalz.me.library.view.RenderView;
/**
* Created by Mr_immortalZ on 2016/10/24.
* email : mr_immortalz@qq.com
*/
public abstract class ColorShowMethod extends ShowMethod {
protected int startColor;
public int endColor;
public ColorShowMethod(int startColor, int endColor) {
this.startColor = startColor;
this.endColor = endColor;
}
@Override
public void translate(InfoBean bean, RenderView parent, View child) {
if (startColor != 0) {
startColor = parent.getResources().getColor(startColor);
} else {
startColor = parent.getResources().getColor(R.color.showmethod_start_color);
}
if (endColor != 0) {
endColor = parent.getResources().getColor(endColor);
} else {
endColor = parent.getResources().getColor(R.color.showmethod_end_color);
}
parent.setPaintColor(endColor);
ObjectAnimator colorAnimator = ObjectAnimator.ofInt(parent, "backgroundColor", startColor, endColor);
colorAnimator.setEvaluator(new ArgbEvaluator());
set.playTogether(
ObjectAnimator.ofFloat(child, "translationX", 0, -bean.translationX),
ObjectAnimator.ofFloat(child, "translationY", 0, -bean.translationY),
ObjectAnimator.ofFloat(child, "scaleX", 1),
ObjectAnimator.ofFloat(child, "scaleY", 1),
colorAnimator
);
set.setInterpolator(new AccelerateInterpolator());
set.setDuration(duration).start();
}
}
package immortalz.me.library.method;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;
import immortalz.me.library.R;
import immortalz.me.library.bean.InfoBean;
import immortalz.me.library.view.RenderView;
/**
* Created by Mr_immortalZ on 2016/10/24.
* email : mr_immortalz@qq.com
*/
public class NoneShowMethod extends ShowMethod {
protected int startColor;
protected int endColor;
@Override
public void translate(InfoBean bean, RenderView parent, View child) {
startColor = parent.getResources().getColor(R.color.showmethod_start_color);
endColor = parent.getResources().getColor(R.color.showmethod_end_color);
parent.setPaintColor(endColor);
ObjectAnimator colorAnimator = ObjectAnimator.ofInt(parent, "backgroundColor", startColor, endColor);
colorAnimator.setEvaluator(new ArgbEvaluator());
set.setInterpolator(new AccelerateInterpolator());
set.setDuration(duration).start();
}
@Override
public void loadCopyView(InfoBean bean, ImageView copyView) {
AnimatorSet set = new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(copyView,"rotation",0,90),
ObjectAnimator.ofFloat(copyView, "scaleX", 1, 0),
ObjectAnimator.ofFloat(copyView, "scaleY", 1, 0)
);
set.setInterpolator(new AccelerateInterpolator());
set.setDuration(duration / 4 * 5).start();
}
@Override
public void loadTargetView(InfoBean bean, ImageView targetView) {
}
}
github 地址:https://github.com/ImmortalZ/TransitionHelper