效果图:
![这里写图片描述](https://img-blog.csdn.net/20170801182911683?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjc2MzQ3OTc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
首先,确定一点,这是两个activity,两个activity的共同点就是那个搜索的View。这个View是使用了一种叫做共享元素的概念。Android 5.0自带共享元素的实现,但是有一些缺点比如:不能改变大小, 不能兼容4.X 等等
什么鬼共享元素,让用户看起来是同一个,其实是两个,两个activity都有各自的布局,id都不相同。共享的只有这个搜索View的位置。而且,这个效果的实现,就是平移+缩放动画,其他的位置就是透明度动画。
首页跳转搜索页的代码:
Intent intent = new Intent(MainActivity.this,SearchActivity.class);
int location[] = new int[2];
tvSearch.getLocationOnScreen(location);
intent.putExtra("x",location[0]);
intent.putExtra("y",location[1]);
startActivity(intent);
overridePendingTransition(0,0);
如代码所示,首先获取共享元素的横纵坐标,并通过intent传到目标activity;其次就是overridePendingTransition(0,0)这个方法。用来指定Activity之间的切换动画。Activity的切换动画指的是从一个activity跳转到另外一个activity时的动画;要注意两点:1.它必需紧挨着startActivity()或者finish()函数之后调用” 2.它只在android2.0以及以上版本上适用(无视掉)
再就是SearchActivity了,onCreate方法里面有用的代码就是
tvSearch.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
tvSearch.getViewTreeObserver().removeOnGlobalLayoutListener(this);
performEnterAnimation();
}
});
我们知道在oncreate中View.getWidth和View.getHeight无法获得一个view的高度和宽度,这是因为View组件布局要在onResume回调后完成。所以现在需要使用getViewTreeObserver().addOnGlobalLayoutListener()来获得宽度或者高度。这是获得一个view的宽度和高度的方法之一。
再就是实现动画的类了
private void performEnterAnimation() {
//首先,先拿到偶从前面传过来的值x,y坐标
float originY = getIntent().getIntExtra("y", 0)
int location[] = new int[2]
tvSearch.getLocationOnScreen(location)
final float translateY = originY - (float) location[1]
//其次,放到前一个页面的位置
tvSearch.setY(tvSearch.getY() + translateY)
tvHint.setY(tvSearch.getY() + (tvSearch.getHeight() - tvHint.getHeight()) / 2)
img.setY(tvSearch.getY() + (tvSearch.getHeight() - img.getHeight()) / 2)
float top = getResources().getDisplayMetrics().density * 20
//然后开始三种动画,平移动画(至于坐标位置的算法,你自己算啊)
final ValueAnimator translateVa = ValueAnimator.ofFloat(tvSearch.getY(), top)
translateVa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
tvSearch.setY((Float) valueAnimator.getAnimatedValue())
img.setY(tvSearch.getY() + (tvSearch.getHeight() - img.getHeight()) / 2)
tvHint.setY(tvSearch.getY() + (tvSearch.getHeight() - tvHint.getHeight()) / 2)
tvTextSearch.setY(tvSearch.getY() + (tvSearch.getHeight() - tvTextSearch.getHeight()) / 2)
}
})
//缩放动画
ValueAnimator scaleVa = ValueAnimator.ofFloat(1, 0.8f)
scaleVa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
tvSearch.setScaleX((Float) valueAnimator.getAnimatedValue())
}
})
//透明度动画
ValueAnimator alphaVa = ValueAnimator.ofFloat(0, 1f)
alphaVa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
llContent.setAlpha((Float) valueAnimator.getAnimatedValue())
tvSearch.setAlpha((Float) valueAnimator.getAnimatedValue())
img.setAlpha((Float) valueAnimator.getAnimatedValue())
tvHint.setAlpha((Float) valueAnimator.getAnimatedValue())
}
})
alphaVa.setDuration(500)
translateVa.setDuration(500)
scaleVa.setDuration(500)
alphaVa.start()
translateVa.start()
scaleVa.start()
}
要说的差不多就这么多,再就是一个返回时候的动画了,跟这个差不多,下载项目去瞅瞅,反正又不要钱
项目链接