写在前面:最近沙雕产品说要做我们Android的应用体验太差,引起我心理极度的不平衡,打开ios兄弟的应用一看确实体验和细节方面比我们强了不是一点点.
看到一个动画的确不错,下面是我自己的实现:
效果分解
就是一个伸缩动画+位移的动画.
GridView中的Item 没法放大到整个屏幕
在真正实现的时候还发现一个问题,里面是一个gridView,而gridView中是无法将其中一块拿出来伸缩,我的想法是在上面叠加一个透明层。
动画分解
如果仅仅是一个放大效果,那么如果图片比较大就撑出屏幕,所以加上一个位移,大家可以看到伸缩和位移是同时进行的,所以这里推荐AnimatorSet或者AnimationSet,这两个能支持同时播放动画,AnimatorSet还能改变播放顺序,主要也是用在属性动画。这里用的就是AnimatorSet.
ok,解决了这几个问题开始正式编码,首先加一个透明层,如果是做成全局通用的,正确的做法是打开另外一个界面,在另外一个界面播放动画。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/lv_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent">
<ImageView
android:id="@+id/expandedImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:visibility="visible" />
</RelativeLayout>
要实现覆盖在点击的相片上位置上,那么就要知道这个图片的位置,有点拗口。
`expandedImage.getGlobalVisibleRect
这个函数需要传入一个Rect,这个函数只有在界面创建完成才能被使用,否则返回空,可以使用监听imageView.getViewTreeObserver()
,也可以在这里调用
@Override
public void onAttachedToWindow() {
}
另外需要获得放大后的位置,也有两种方式:
是
lv_container.getGlobalVisibleRect
,lv_container是播放界面的根布局,这里就通过填充好的Rect就可以获取到放大后的位置了。2,另外一种方式是获取屏幕的宽度和高度通过计算获取放到后的位置,但是这里需要计算的时候需要注意屏幕的状态栏和操作栏,另外4.0后部分手机底部按键变成了软件盘,这里也是需要算进去。
OK,先是做一个单纯的位移,用到的是这个控件的x y ,这里的x y 对应Rect的 left 和 top,let’s go
AnimatorSet set = new AnimatorSet();
set.play(ObjectAnimator.ofFloat(mExpandedImageView,View.X, startBound.left,finalBounds.left))
.with(ObjectAnimator.ofFloat(mExpandedImageView, View.Y, startBound.top, finalBounds.top));
set.setDuration(mShortAnimationDuration);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(zoomInListenerListener);
set.start();
startBound 是GirdView中item所填充好的Rect,finalBound 是放大后的Rect.这样一个简单的位移做好了.
缩放动画怎么做呢,我所知道的也有两种,第一种,改变控件的宽高,但是as you know ,3.0后的属性动画是无法直接修改的这个值的,那怎么办呢,
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mExpandedImageView, "cyy", startBound.height(), finalHeight);
objectAnimator.setDuration(mShortAnimationDuration);
objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int height = (int) Math.ceil(Double.valueOf((animation.getAnimatedValue("cyy").toString())));
mExpandedImageView.getLayoutParams().height = height;
mExpandedImageView.requestLayout();
}
});
*
对属性动画属性的应该并不陌生,我也是查了好多资料才发现,android
开始流行的时候是2.0,属性动画3.0才出,当时3.0并不是主流,而且当时Android手机普遍较差,播放一个动画只能看到一个开始晃一下就过去了,等出4.0 的时候,2.0还是主流,但是属性动画还不能兼容2.0一下,估计支持了也没什么卵用,机器太渣,现在Android机器都是4.0以上,硬件也是升级了好几次,不由的让人感叹互联网技术升级真的好快。
*
点击回复到原先位置的动画跟这个差不多,你已经知道了开始位置和结束位置,调用起来很简单,另外改变宽高的方法是改变控件的Scale,View.scale_y,View.Scale_x.
如果想在放大后加一个滑动效果,也很简单,在播放动画界面加一个ViewPage,等动画放大后显示ViewPage,在ViewPage的OnitemClick事件中播放结束动画。只要算好放大后的位置,用户是感觉不出来expandView和Viewpage切换的。
我现在的这种做法还有问题,那就是在girdView中图片是center_corp ,如果在放大后还是center_corp会导致图片模糊,所以用的是fit_center,所以在播放的时候会与原图不一致,这里在csdn中找一篇解决方案解决动画过渡问题
有时间我再把我的代码整理发出来