上图动画是你想要的吗?如果是yes , 那么恭喜你,这篇文章你找对了;如果是no ,或许你可以先收藏,在需要的时候再打开看看....
言归正传,由于项目需要——在一个简介页面打开详情页时要对简介页面的图片平滑过渡到详情页,问了度娘,google几乎都是通过在xml中定义动画,显然这个不符合我们的需求。曾也尝试了开源框架,可惜向下兼容有问题........
该库的使用简单的超乎你的想象......首先,去下载动画库
然后只需在view的点击事件中添加如下代码:
AnimHelper.launchActivity(Activity activity, View v, Intent intent) ;
在activity的onCreate中添加如下代码:
AnimHelper ah = new AnimHelper(getIntent());
ah.start(动画view的父view, 做动画的view, 400, null);
退出activity的地方添加如下代码:
ah.exit(this, 退出时做动画的view, null);
好啦,做完以上内容就可以实现上图的效果了。
如果您不满足于拿来使用,可以继续往下看:
下面我们来看看原理图:
首先我们点击的是 activityA中的fromView , 跳转的目标页面为 ActivityB(任意布局),我们要将fromView通过缩放,平移到 toView 。
于是我们首先将toview 通过缩放,平移到 虚拟的 fromView位置,然后再通过动画还原到toView位置。
在这里我们需要解决几个坐标问题:
1.fromView的坐标(这里取相对于屏幕绝对坐标)
2.toView的坐标 (toView的可见区域是由父View控制,所以不能直接取屏幕坐标)
3.toView父View (下面称容器)的坐标 (这里取屏幕绝对坐标)
如此,通过屏幕坐标系将fromView和 容器联系起来,就可以计算 mockView的位置,然后通过缩放就可以回到toView的位置。
原理就是这样啦,代码是通过属性动画实现的,下面给出进入时的动画源码(有兴趣的同学,可以自行写退出的动画):
/**
* @param pv the direct parent view of to
* @param to the animation view
* @param duration animation duration
* @param al
*/
public void start(View pv, View to, int duration, final Animator.AnimatorListener al) {
parentView = pv;
toView = to;
dur = duration > MIN_DURATION ? duration : MIN_DURATION;
if (parentView != null && toView != null) {
toView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
toView.getViewTreeObserver().removeOnPreDrawListener(this);
int l[] = new int[2];
parentView.getLocationOnScreen(l);
RectF parent = new RectF(l[0], l[1], l[0] + parentView.getMeasuredWidth(),
l[1] + parentView.getMeasuredHeight());
toView.getLocationOnScreen(l);
ad.toViewRect.set(l[0], l[1], l[0] + toView.getMeasuredWidth(),
l[1] + toView.getMeasuredHeight());
ad.pointRelativeX = ad.srcIn.left - parent.left;
ad.pointRelativeY = ad.srcIn.top - parent.top;
ad.sx = ad.srcIn.width() / ad.toViewRect.width();
ad.sy = ad.srcIn.height() / ad.toViewRect.height();
ad.tx = (ad.srcIn.width() - ad.toViewRect.width()) / 2;
ad.ty = (ad.srcIn.height() - ad.toViewRect.height()) / 2;
ObjectAnimator alpha = ObjectAnimator.ofFloat(parentView, View.ALPHA, 0, 1);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(toView, View.SCALE_X, ad.sx, 1);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(toView, View.SCALE_Y, ad.sy, 1);
ObjectAnimator transX = ObjectAnimator.ofFloat(toView, View.TRANSLATION_X, ad.tx + ad.pointRelativeX, 0);
ObjectAnimator transY = ObjectAnimator.ofFloat(toView, View.TRANSLATION_Y, ad.ty + ad.pointRelativeY, 0);
AnimatorSet animation = new AnimatorSet();
animation.setDuration(dur);
animation.setInterpolator(new AccelerateDecelerateInterpolator());
animation.playTogether(scaleX, scaleY, transX, transY, alpha);
if (al != null) {
animation.addListener(al);
}
animation.start();
return true;
}
});
}
}
借助动画库