Android5.0上的元素共享和CircleReveal效果

先看效果图
gif效果图

这个效果通过元素共享和CircleReveal共同完成,当然是有先后顺序的,先执行元素共享效果,元素共享过渡效果执行完,执行CirclerReveal动画下面介绍实现方法,代码很少,文章最后有项目下载。

  • 共享元素
    元素共享是一个activity或fragment切换时候一个过渡效果。如果前一个界面A的元素a和后一界面B的元素b两个元素共享,使用元素共享效果从界面A切换到界面B可以看到,a移动到b处并在移动过程中变为b的外观和大小;如果关闭界面B回到界面A同样看到相反的过渡效果。所以说共享元素动画效果取决于两个共享元素的位置和外观。共享元素的实现应该不是真的实现了控件元素的位移和大小外观变化,只是的一种动画效果。

1、使用共享元素必须满足条件:
(1)主题需要是Theme.AppCompat下主题,才能看到共享元素效果;(2)因为共享元素是Android5.0引入的,所以需在android5.0(LOLLIPOP)以上系统下运行,低版本运行会报错,需加上

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){

}

2、共享元素的设置:
在代码中设置:
view.setTransitionName( getString(R.string.transition_name));
在xml文件中设置:
android:transitionName=”@string/transition_name”
实现元素共享效果前后两个界面的元素共享名字TransitionName必须相同,设置任意的字符串即可。
3、界面A切换到B元素共享调用方法:
创建一个ActivityOptions,通过toBundle()方法,ActivityOptions转换成Bundle,用于startActivity传递bundle。ActivityOptions通过makeSceneTransitionAnimation方法在两个activity之间产生过渡效果。
makeSceneTransitionAnimation源码如下:

public static ActivityOptions makeSceneTransitionAnimation(
    Activity activity,View sharedElement, String sharedElementName) {
        return makeSceneTransitionAnimation(
            activity, Pair.create(sharedElement, sharedElementName));
    }

看到源码就很好理解,参数1是当前使用共享元素的activity,参数2是共享的view,参数3是共享名,这个值不能为null。
代码实现,

ActivityOptions options = ActivityOptions
    .makeSceneTransitionAnimation(MainActivity.this,
    view, view.getTransitionName());
startActivityForResult(intent, 1, options.toBundle());

这样便可实现共享动画效果。

  • CircleReveal
    CircleReveal实现圆形缩放效果,可突出显示某个部分。也是android5.0引入的效果,和共享元素一样在低版本上运行会报错。
    实现方法:
    调用ViewAnimationUtils下的createCircularReveal方法,方法返回一个Animator对象,这个Animator可以设置动画响应属性,调用start方法开始播放动画,可以看出CircularReveal是一个属性动画,动画设置同属性动画的即可。
    下面是createCircularReveal方法源码,
/* @param view The View will be clipped to the animating circle.
* @param centerX The x coordinate of the center of the animating circle, relative to
*                <code>view</code>.
* @param centerY The y coordinate of the center of the animating circle, relative to
*                <code>view</code>.
* @param startRadius The starting radius of the animating circle.
* @param endRadius The ending radius of the animating circle.
*/
public static Animator createCircularReveal(View view,
            int centerX,  int centerY, float startRadius, float endRadius) {
        return new RevealAnimator(view, centerX, centerY, startRadius, endRadius);
    }

从源码中可以看出,参数1是执行动画的控件,注意这个控件不是我们想突出显示的控件,是想执行圆形展开或缩放效果的控件或布局,参数2、3是开始执行动画圆形的圆心的x坐标和y坐标,参数4是开始的半径,参数5是结束的半径。
了解传递参数让我们来看看代码部分,header是圆形缩放的中心控件,rl是RelativeLayout,是要执行动画的布局,header在布局rl中。
代码实现部分,

Animator anim = ViewAnimationUtils.createCircularReveal(
                    rl,
                    (header.getLeft() + header.getRight()) / 2,
                    (header.getTop() + header.getBottom()) / 2,
                    (float) header.getWidth() / 2,
                    finalRadius);
anim.setDuration(1000);
anim.setInterpolator(new AccelerateDecelerateInterpolator());
            anim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    super.onAnimationStart(animation);
                    Log.e("---", "start anim");
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    Log.e("---", "end anim");
                    //show views
                }
            });
anim.start();

finalRadius取的是圆形能覆盖住整个rl的最小值,也就是rl这个矩形的斜角线长。

final float finalRadius = (float) Math.hypot(rl.getWidth(), rl.getHeight());

这样CircleReveal动画就实现了。

为了两个动画平滑的连接在一起,也就是先执行activity切换的共享元元素过渡效果,再制定CircleReveal圆形展开效果,我们需要拿到元素共享效过渡效果的监听。
在Activity B中 通过

Transition transition = getWindow().getSharedElementEnterTransition();

可以拿到Transition对象,为transition添加监听,可以监听到过渡动画结束,

transition.addListener(new Transition.TransitionListener() {
                @Override
                public void onTransitionStart(Transition transition) {

                }

                @Override//过渡结束
                public void onTransitionEnd(Transition transition) {
                    performCircleReveal();//执行CircleReveal动画
                }

                @Override
                public void onTransitionCancel(Transition transition) {

                }

                @Override
                public void onTransitionPause(Transition transition) {

                }

                @Override
                public void onTransitionResume(Transition transition) {

                }
            });

在onTransitionEnd方法中,执行CircleReveal动画。

这样这个切换Activity的效果就完成了,fragment切换也可以实现元素共享效果,大家可以自行去实现。

附: 源码地址:
http://download.csdn.net/detail/tm1989tm/9478015

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值