TransitionHelper activity 跳转过渡动画

提供了一种简单的方法来实现复杂的过渡动画效果。该库包括一个核心类`TransitionsHelper`,用于处理活动之间的过渡动画,以及几种不同的显示方法,如`InflateShowMethod`和`ColorShowMethod`等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

核心类:

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







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值