看微信朋友圈的时候,当我们点击图片,图片会从点击的图片位置,逐渐放大,移动到正中间。退出图片查看器的时候,图片会逐渐变小,移到初始位置。对于用户来说,这是一种非常好的体验效果。
于是,自己手动撸了一个进场退场的动画。具体参见下图
下面,开始介绍实现原理。
原理解析先对上面的动画进行分析:
点击后,是重新打开了一个 activity,当然也可以是一个 fragment,都可以。图片是从原始位置逐渐放大移到那个到中间位置的。这个过程都发生在打开后的页面中。
再次点击图片,退出的时候,先做动画,在移除原有的acticity.通过上面的分析,我们已经知道粗略的技术方案了,接下去就是解决一些细节问题。
从第一个页面打开到第二个页面,需要传递什么参数?首先是,图片的位置信息,只有这样我们才可以将图片从原始位置逐步放大。下面我们开始获取图片的坐标参数:
/** * 获取图片的位置信息 */ public ArrayList getimagePos(VIEw vIEw) { int[] locat = new int[2]; vIEw.getLocationOnScreen(locat); int wIDth = vIEw.getWIDth(); int height = vIEw.getHeight(); ArrayList<Integer> posArr = new ArrayList<>(); posArr.add(locat[0]); posArr.add(locat[0] + wIDth); posArr.add(locat[1]); posArr.add(locat[1] + height); return posArr; }
将图片的位置信息传给新的 actvity :
// 点击事件 VIEw.OnClickListener onClickListener = new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw v) { int pos = mRecyclerVIEw.getChildAdapterposition(v); Intent intent = Intent(); intent.setClass(mContext,Main2Activity.class); intent.putIntegerArrayListExtra(POS_ARRAY,getimagePos(v)); intent.putExtra(IMAGE_POS,pos); startActivity(intent); overrIDePendingTransition(0,0); } };
注意需要去除原有的 activity 的默认动画。避免影响图片的动画效果。
如何让图片从原始位置动起来?在做动画前,需要做一些准备工作,比如计算可显示图片的屏幕宽高,放大系数,移动系数等。
/** * 计算动画位移和缩放 private computeranimationParams() { if (mPosArr.size() != 4) { ; } int screenHigh = mMetrics.heightPixels; int screenWIDth = mMetrics.wIDthPixels; // 计算可用于显示图片的屏幕高度 int availableScreenHeight = screenHigh - getStatusbarHeight(); int imageHeight = mPosArr.get(3) - mPosArr.get(2); mOriginWIDth = mPosArr.get(1) - mPosArr.get(0); float radioWIDth = screenWIDth * 1.0f / mOriginWIDth; float radioHeight = availableScreenHeight * 1.0f / imageHeight; 获取放大系数 mRadio = Math.min(radioHeight,radioWIDth); 计算位移距离,屏幕中心与图片中心的距离, mTransition[0] = (float) (screenWIDth / 2 - (mPosArr.get(0) + (mPosArr.get(1) - mPosArr.get(0)) / 2)); mTransition[1] = (float) ((availableScreenHeight) / 2 - (mPosArr.get(2) - getStatusbarHeight() + (mPosArr.get(3) - mPosArr.get(2)) / 2)); }
具体可以参考上面的代码,记得要考虑状态栏对于动画的影响。计算好了之后,我们得将现有的图片先设置成原始大小:
* 动画前的准备工作 * doReadyJob() { 需要对图片的宽度进行调整 FrameLayout.LayoutParams params = FrameLayout.LayoutParams(mOriginWIDth,FrameLayout.LayoutParams.MATCH_PARENT); params.setmargins(mPosArr.get(0),mPosArr.get(1),1)">); mImageVIEw.setLayoutParams(params); }
一切准备就绪后,我们得将图片从原始位置移动到正中间。下面就是动画实现细节:
* 模拟入场动画 showEnteranim() { final ValueAnimator enteranimator = ValueAnimator.offloat(0f,1f).setDuration(DURATION_IN); enteranimator.setInterpolator( AccelerateDecelerateInterpolator()); enteranimator.addUpdateListener( ValueAnimator.AnimatorUpdateListener() { @OverrIDe onAnimationUpdate(ValueAnimator animation) { float value = (float) animation.getAnimatedValue(); mImageVIEw.setAlpha(1f); mImageVIEw.setScaleX(1 + (mRadio - 1) * value); mImageVIEw.setScaleY(1 + (mRadio - 1) * value); mImageVIEw.setTranslationX(mTransition[0] * value); mImageVIEw.setTranslationY(-mTransition[1] * (1f - value)); mImageVIEw.invalIDate(); } }); enteranimator.start(); }
这里我们通过 ValueAnimator 来控制更新动画进度。到这里,图片的进场动画就完成了。
对于退场动画,原理是一样的:
* 模拟退场动画 showOutAnim() { final ValueAnimator exitAnimator = ValueAnimator.offloat(1f,0f).setDuration(DURATION_IN); mImageVIEw.setAlpha(1f); exitAnimator.setInterpolator( AccelerateDecelerateInterpolator()); exitAnimator.addUpdateListener() animation.getAnimatedValue(); mImageVIEw.setScaleX((mRadio - 1) * value + 1); mImageVIEw.setScaleY((mRadio - 1) * value + 1); mImageVIEw.setTranslationX(mTransition[0] * value)); } }); exitAnimator.addListener( AnimatorListenerAdapter() { @OverrIDe onAnimationEnd(Animator animation) { quitactivityWithoutAnimation(); } }); exitAnimator.start(); }
到这里,动画的主要原理已经剖析完成。
源码: https://github.com/huanshen/PictureViewer
目前这个比较简单,真的在项目实现起来的时候,代码量还是蛮多的,并且考虑的也要更多。
比如,你还得传递图片的 url,图片查看器中图片可放大缩小,拖拽等。
总结以上是内存溢出为你收集整理的仿微信图片查看器入场退场动画全部内容,希望文章能够帮你解决仿微信图片查看器入场退场动画所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)