前几篇中, 我们说了安卓的补间动画和插值器, 这一篇, 我们来写 2 个例子.
[Android 动画] 动画详解之补间动画 (一) https://www.jianshu.com/p/abeca56da5e4
[Android 动画] 动画详解之插值器 (二) https://www.jianshu.com/p/80933d36b6fc
[Android 动画] 动画详解之属性动画 (三) https://www.jianshu.com/p/ffd57179f1ce
[Android 动画] 动画详解之仿微信查看大图效果 (四) https://www.jianshu.com/p/b2de4607308a
[Android 动画] 动画详解之属性动画 (五) https://www.jianshu.com/p/3576f2661bd4
一, 小球落地动画
先上效果图:
可以看到, 小球是先加速下落, 碰到底部后弹起, 再下落, 最后完全静止, 如果要手写这个过程, 还是相当麻烦的, 有没有简单的办法? 这里就要用到我们第 2 篇中说到过的 BounceInterpolator 插值器. 详情请看 [Android 动画] 动画详解之插值器 (二) https://www.jianshu.com/p/80933d36b6fc
- translateAnimation = new TranslateAnimation(0, 0, 0, DensityUtils.dp2px(BallActivity.this, 400));
- translateAnimation.setDuration(2000);
- translateAnimation.setFillAfter(true);
- translateAnimation.setInterpolator(new BounceInterpolator());
- tvDemo.startAnimation(translateAnimation);
二, 仿微信查看大图效果
相信大家都有留意微信的查看大图动画, 它会由图片当前在屏幕中的位置渐渐放大移动到屏幕中心, 简单来说的话就是一个缩放 + 透明度动画. 先上效果图:
之前在第一篇中, 我们说过, 缩放动画的取值可以是具体数值, 相对于自身, 相对于父布局这 3 种, 这里就需要使用相对于父布局这种.
首先, 我们需要获取点击按钮在屏幕中的坐标. 先定义一个 int 数据用于存放坐标, 然后调用 getLocationOnScreen 方法即可获取该控件在屏幕中的坐标
- int[] location = new int[2];
- btnTopLeft.getLocationOnScreen(location);
然后, 计算该坐标相对于屏幕的百分比
- pointx = getIntent().getIntExtra(POINTX, 0);
- pointy = getIntent().getIntExtra(POINTY, 0);
- DisplayMetrics metrics = getResources().getDisplayMetrics();
- if (pointx == 0) {
- pointXValue = 0.5f;
- } else {
- pointXValue = pointx / metrics.widthPixels;
- }
- if (pointy == 0) {
- pointYValue = 0.5f;
- } else {
- pointYValue = pointy / metrics.heightPixels;
- }
添加动画
- AnimationSet animationSet = new AnimationSet(true);
- AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
- ScaleAnimation scaleAnimation = new ScaleAnimation(0, 1f, 0, 1f, ScaleAnimation.RELATIVE_TO_PARENT,
- pointXValue, ScaleAnimation.RELATIVE_TO_PARENT, pointYValue);
- animationSet.addAnimation(alphaAnimation);
- animationSet.addAnimation(scaleAnimation);
- animationSet.setDuration(500);
- animationSet.setFillAfter(true);
- ivImg.startAnimation(animationSet);
处理返回, 重写 onBackPressed 方法, 返回时, 与进入的动画正好相反
- @Override
- public void onBackPressed() {
- AnimationSet animationSet = new AnimationSet(true);
- AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
- ScaleAnimation scaleAnimation = new ScaleAnimation(1f, 0, 1f, 0, ScaleAnimation.RELATIVE_TO_PARENT,
- pointXValue, ScaleAnimation.RELATIVE_TO_PARENT, pointYValue);
- animationSet.addAnimation(alphaAnimation);
- animationSet.addAnimation(scaleAnimation);
- animationSet.setDuration(500);
- animationSet.setFillAfter(true);
- animationSet.setAnimationListener(new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
- }
- @Override
- public void onAnimationEnd(Animation animation) {
- ImgActivity.super.onBackPressed();
- }
- @Override
- public void onAnimationRepeat(Animation animation) {
- }
- });
- ivImg.startAnimation(animationSet);
- }
还需要处理默认的 Activity 切换动画, 以及 Activity 的默认背景
- startActivity(intent);
- overridePendingTransition(0, 0);
设置目标 Activity 的主题
- <activity
- Android:name=".demo.ImgActivity"
- Android:theme="@style/transparent"></activity>
- <style name="transparent" parent="Theme.AppCompat.Light.NoActionBar">
- <item name="android:windowIsTranslucent">true</item>
- <item name="android:windowBackground">@Android:color/transparent</item>
- </style>
当我们运行时会发现, 动画的起始位置是按钮的左上角, 原来使用 getLocationOnScreen 获取的是控件左上角的坐标, 所以我们需要加上控件宽高的 1/2. TIP: 由于此处所有按钮的宽高都一样, 所以就取了同一个.
- Intent intent = new Intent(WXPicActivity.this, ImgActivity.class);
- int[] location = new int[2];
- switch (view.getId()) {
- case R.id.btn_top_left:
- btnTopLeft.getLocationOnScreen(location);
- break;
- case R.id.btn_top_right:
- btnTopRight.getLocationOnScreen(location);
- break;
- case R.id.btn_bottom_left:
- btnBottomLeft.getLocationOnScreen(location);
- break;
- case R.id.btn_bottom_right:
- btnBottomRight.getLocationOnScreen(location);
- break;
- case R.id.btn_center:
- btnCenter.getLocationOnScreen(location);
- break;
- }
- intent.putExtra(ImgActivity.POINTX, location[0] + btnCenter.getMeasuredWidth() / 2);
- intent.putExtra(ImgActivity.POINTY, location[1] + btnCenter.getMeasuredHeight() / 2);
- startActivity(intent);
- overridePendingTransition(0, 0);
最后献上源码 https://github.com/18702953620/AnimDemo
你的认可, 是我坚持更新博客的动力, 如果觉得有用, 就请点个赞, 谢谢
来源: https://juejin.im/post/5c7494715188252b194eaf1c