Android Animation学习 实现 IOS 滤镜退出动画

IOS的用户体验做的很好,其中一点很重要的地方就是动画效果。

最近在学习Android的Animation,简单实现了一个IOS相机滤镜退出的动画:

布局文件:activity_animation_demo.xml  布局未考虑各个分辨率,只是为了实现动画逻辑,(代码测试是在720P分辨率的手机上)

  1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2     xmlns:tools="http://schemas.android.com/tools"
  3     android:layout_width="match_parent"
  4     android:layout_height="match_parent"
  5     tools:context="com.example.andanimationdemo.AnimationDemoActivity" >
  6
  7     <FrameLayout
  8         android:layout_width="wrap_content"
  9         android:layout_height="wrap_content"
 10         android:layout_marginTop="50dp"
 11         android:layout_marginLeft="25px"
 12         android:layout_marginRight="25px"
 13         >
 14         <LinearLayout
 15             android:id="@+id/rootLinearLayout"
 16             android:layout_width="wrap_content"
 17             android:layout_height="wrap_content"
 18             android:orientation="vertical"
 19             >
 20             <LinearLayout
 21                 android:id="@+id/firstLinearLayout"
 22                 android:orientation="horizontal"
 23                 android:layout_width="wrap_content"
 24                 android:layout_height="wrap_content">
 25                 <Button
 26                     android:id="@+id/Button_1"
 27                     android:layout_width="200px"
 28                     android:layout_height="200px"
 29                     android:background="@android:color/holo_blue_bright"/>
 30                 <Button
 31                     android:id="@+id/Button_2"
 32                     android:layout_width="200px"
 33                     android:layout_height="200px"
 34                     android:layout_marginLeft="35px"
 35                     android:background="@android:color/holo_green_light"/>
 36                 <Button
 37                     android:layout_marginLeft="35px"
 38                     android:id="@+id/Button_3"
 39                     android:layout_width="200px"
 40                     android:layout_height="200px"
 41                     android:background="@android:color/black"/>
 42             </LinearLayout>
 43
 44             <LinearLayout
 45                 android:id="@+id/SencondLinearLayout"
 46                 android:layout_marginTop="35px"
 47                 android:orientation="horizontal"
 48                 android:layout_width="wrap_content"
 49                 android:layout_height="wrap_content">
 50                 <Button
 51                     android:id="@+id/Button_4"
 52                     android:layout_width="200px"
 53                     android:layout_height="200px"
 54                     android:background="@android:color/holo_orange_dark"/>
 55                 <Button
 56                     android:id="@+id/Button_5"
 57                     android:layout_width="200px"
 58                     android:layout_height="200px"
 59                     android:layout_marginLeft="35px"
 60                     android:background="@android:color/holo_red_light"/>
 61                 <Button
 62                     android:layout_marginLeft="35px"
 63                     android:id="@+id/Button_6"
 64                     android:layout_width="200px"
 65                     android:layout_height="200px"
 66                     android:background="@android:color/darker_gray"/>
 67             </LinearLayout>
 68
 69             <LinearLayout
 70                 android:id="@+id/ThirdLinearLayout"
 71                 android:layout_marginTop="35px"
 72                 android:orientation="horizontal"
 73                 android:layout_width="wrap_content"
 74                 android:layout_height="wrap_content">
 75                 <Button
 76                     android:id="@+id/Button_7"
 77                     android:layout_width="200px"
 78                     android:layout_height="200px"
 79                     android:background="@android:color/holo_green_light"/>
 80                 <Button
 81                     android:id="@+id/Button_8"
 82                     android:layout_width="200px"
 83                     android:layout_height="200px"
 84                     android:layout_marginLeft="35px"
 85                     android:background="@android:color/holo_orange_light"/>
 86                 <Button
 87                     android:layout_marginLeft="35px"
 88                     android:id="@+id/Button_9"
 89                     android:layout_width="200px"
 90                     android:layout_height="200px"
 91                     android:background="@android:color/holo_blue_light"/>
 92             </LinearLayout>
 93         </LinearLayout>
 94     </FrameLayout>
 95
 96     <Button
 97         android:id="@+id/Reset"
 98         android:layout_width="wrap_content"
 99         android:layout_height="wrap_content"
100         android:layout_alignParentRight="true"
101         android:layout_alignParentBottom="true"
102         android:layout_marginRight="40dp"
103         android:layout_marginBottom="40dp"
104         android:text="Reset"></Button>
105
106 </RelativeLayout>

AnimationDemoActivity.java

  1 package com.example.andanimationdemo;
  2
  3 import android.app.Activity;
  4 import android.os.Bundle;
  5 import android.util.Log;
  6 import android.view.View;
  7 import android.view.View.OnClickListener;
  8 import android.view.animation.Animation;
  9 import android.view.animation.Animation.AnimationListener;
 10 import android.view.animation.ScaleAnimation;
 11 import android.widget.Button;
 12 import android.widget.LinearLayout;
 13
 14 public class AnimationDemoActivity extends Activity implements OnClickListener{
 15
 16     private static final String TAG = "AnimationDemo";
 17     LinearLayout rootLinearLayout;
 18     Button resetButton;
 19     int mCurrentClickButtonId = -1;
 20
 21     int[] ButtonID = new int[] {
 22         R.id.Button_1,R.id.Button_2,R.id.Button_3,
 23         R.id.Button_4,R.id.Button_5,R.id.Button_6,
 24         R.id.Button_7,R.id.Button_8,R.id.Button_9
 25     };
 26
 27     @Override
 28     protected void onCreate(Bundle savedInstanceState) {
 29         super.onCreate(savedInstanceState);
 30         setContentView(R.layout.activity_animation_demo);
 31         rootLinearLayout = (LinearLayout) findViewById(R.id.rootLinearLayout);
 32         resetButton = (Button) findViewById(R.id.Reset);
 33         setButtonListener();
 34     }
 35
 36     private void setButtonListener() {
 37         for (int i = 0; i < ButtonID.length; i++) {
 38             rootLinearLayout.findViewById(ButtonID[i]).setOnClickListener(this);
 39         }
 40         resetButton.setOnClickListener(this);
 41     }
 42
 43     /**
 44      * 点击某个按钮后,开始放大动画
 45      * 这里提供的是一个思路,并不局限于当前布局,放大倍数,通过哪个点放大,都可以计算出来。
 46      */
 47     boolean onAnimationRunning = false;
 48
 49     public void onAnimationButtonClick() {
 50         Log.d(TAG, "onAnimationButtonClick");
 51         int[] position = new int[2];
 52         int[] ButtonPosition = new int[2];
 53         Button AnimaitonBtton = (Button) rootLinearLayout.findViewById(ButtonID[mCurrentClickButtonId - 1]);
 54         rootLinearLayout.getLocationInWindow(position);
 55         AnimaitonBtton.getLocationInWindow(ButtonPosition);
 56         int rootWidth = rootLinearLayout.getWidth();
 57         int rootHeight = rootLinearLayout.getHeight();
 58         int ButtonWidth = AnimaitonBtton.getWidth();
 59         int ButtonHeight = AnimaitonBtton.getHeight();
 60
 61         /**
 62          * 计算 scale factor
 63          */
 64         float widthRate = (float)rootWidth/ButtonWidth;
 65         float heightRate = (float)rootHeight/ButtonHeight;
 66
 67         /**
 68          * 计算放大的中心点
 69          */
 70         float PointA = (ButtonPosition[0] - position[0]) * widthRate / (widthRate - 1);
 71         float PointB = (ButtonPosition[1] - position[1]) * heightRate / (heightRate - 1);
 72
 73         onAnimationRunning = true;
 74         ScaleAnimation mScaleAnimation = new ScaleAnimation(1.0f, widthRate, 1.0f, heightRate,PointA,PointB);
 75         mScaleAnimation.setDuration(2000);
 76         mScaleAnimation.setFillAfter(true);
 77         mScaleAnimation.setAnimationListener(new AnimationListener() {
 78
 79             @Override
 80             public void onAnimationStart(Animation animation) {
 81             }
 82
 83             @Override
 84             public void onAnimationRepeat(Animation animation) {
 85             }
 86
 87             @Override
 88             public void onAnimationEnd(Animation animation) {
 89                 Log.d(TAG,"onAnimationEnd");
 90                 onAnimationRunning = false;
 91                 for (int i = 0; i< ButtonID.length; i++) {
 92                     rootLinearLayout.findViewById(ButtonID[i]).setEnabled(false);
 93                 }
 94             }
 95         });
 96         rootLinearLayout.startAnimation(mScaleAnimation);
 97
 98     }
 99
100     @Override
101     public void onClick(View v) {
102         // TODO Auto-generated method stub
103         Log.d(TAG, "onClick :" + v.getId());
104         if (onAnimationRunning) {
105             Log.d(TAG, "onAnimationRunning = true");
106             return;
107         }
108
109         switch (v.getId()) {
110         case R.id.Button_1:
111             mCurrentClickButtonId = 1;
112             onAnimationButtonClick();
113             break;
114         case R.id.Button_2:
115             mCurrentClickButtonId = 2;
116             onAnimationButtonClick();
117             break;
118         case R.id.Button_3:
119             mCurrentClickButtonId = 3;
120             onAnimationButtonClick();
121             break;
122         case R.id.Button_4:
123             mCurrentClickButtonId = 4;
124             onAnimationButtonClick();
125             break;
126         case R.id.Button_5:
127             mCurrentClickButtonId = 5;
128             onAnimationButtonClick();
129             break;
130         case R.id.Button_6:
131             mCurrentClickButtonId = 6;
132             onAnimationButtonClick();
133             break;
134         case R.id.Button_7:
135             mCurrentClickButtonId = 7;
136             onAnimationButtonClick();
137             break;
138         case R.id.Button_8:
139             mCurrentClickButtonId = 8;
140             onAnimationButtonClick();
141             break;
142         case R.id.Button_9:
143             mCurrentClickButtonId = 9;
144             onAnimationButtonClick();
145             break;
146         case R.id.Reset:
147             mCurrentClickButtonId = -1;
148             rootLinearLayout.clearAnimation();
149             rootLinearLayout.postInvalidate();
150             for (int i = 0; i< ButtonID.length; i++) {
151                 rootLinearLayout.findViewById(ButtonID[i]).setEnabled(true);
152             }
153             break;
154         default:
155             break;
156         }
157     }
158 }

点击某个Button后,可以通过它所在的位置坐标,以及父布局所在的位置坐标,计算出通过哪个点放大。

实现的效果如下图:

如有什么不对的地方,还望大神指正。

时间: 2024-10-12 15:56:51

Android Animation学习 实现 IOS 滤镜退出动画的相关文章

Android Animation学习(二) ApiDemos解析:基本Animatiors使用

Animator类提供了创建动画的基本结构,但是一般使用的是它的子类: ValueAnimator.ObjectAnimator.AnimatorSet ApiDemos中Animation部分是单独的一个包. 下面代码来自ApiDemos中的AnimationCloning类,加了一个使用ValueAnimator的动画,还有一些注释. 完整的项目见:URL:https://github.com/mengdd/AnimationApiDemos.git package com.example.

Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition

Property animation系统还提供了对ViewGroup中的View改变加入动画的功能. 你可以使用 LayoutTransition 对ViewGroup中的View改变进行动画显示. 注意,本文所说的动画效果都是设置给容器(ViewGroup),然而效果是通过容器存放的View来体现的. 四种容器转换动画类型 当你添加或者移除ViewGroup中的View时,或者你调用View的setVisibility()方法来控制其显示或消失时,就处于一个转换状态.这种事件就有可能会激发动画

Android Animation学习笔记

关于动画的实现,Android提供了Animation,在Android SDK介绍了2种Animation模式: 1. Tween Animation:通过对场景里的对象不断做图像变换(平移.缩放.旋转)产生动画效果,即是一种渐变动画: 2. Frame Animation:顺序播放事先做好的图像,是一种画面转换动画. 动画类型 下面先来看看Android提供的动画类型.Android的animation由四种类型组成 在XML文件中: alpha        渐变透明度动画效果 scale

Android Animation学习(一) Property Animation介绍

Android Animation Android framework提供了两种动画系统: property animation (introduced in Android 3.0)和view animation. 除了这两种系统外,也可以利用Drawable animation,也就是播放序列帧图像. 所以,Android中的Animation分三种: 1. Property Animation 2. View Animation 3. Drawable Animation 下面主要说Pro

Android Animation学习(六) View Animation介绍

View Animation View animation系统可以用来执行View上的Tween animation和Frame animation. Tween animation可以在View对象上执行一系列的简单变换,比如位置.尺寸.旋转.透明度等. animation package 包中包含了tween animation所有的类. 一系列的动画命令定义了一个完整的tween animation,可以用代码定义也可以用XML资源文件定义. XML资源文件 XML资源文件的使用可以见:A

Android Animation学习(三) ApiDemos解析:XML动画文件的使用

可以用XML文件来定义Animation. 文件必须有一个唯一的根节点: <set>, <objectAnimator>, or <valueAnimator>三者之一. 对应的Java类是: ValueAnimator - <animator> ObjectAnimator - <objectAnimator> AnimatorSet - <set> <set>标签是可以嵌套的. <set>标签的androi

Android Animation学习(四) ApiDemos解析:多属性动画

如果想同时改变多个属性,根据前面所学的,比较显而易见的一种思路是构造多个对象Animator , ( Animator可以是ValueAnimator.ObjectAnimator和AnimatorSet) 然后最后把它们放在一个AnimatorSet中. 另一种思路就是,把多个属性的改变放在同一个 ValueAnimator 中(ObjectAnimator也是 ValueAnimator). 而这就要借助PropertyValuesHolder.本文主要讲这种方法. PropertyValu

Android Animation学习

关于动画的实现,android提供了Animation,有两种Animation(动画)模式 1. Tween Animation:通过对场景里的对象不断做图像变换(平移.缩放.旋转)产生动画效果,即是一种渐变动画: 2. Frame Animation:顺序播放事先做好的图像,是一种画面转换动画. 动画类型: Android的animation由四种类型组成 在XML文件中: |--alpha    渐变透明度变化效果 |--scale    渐变尺寸伸缩动画效果 |--translate  

[转]Android Activity和Fragment的转场动画

Android Activity和Fragment的转场动画 Activity转场动画 Activity的转场动画是通过overridePendingTransition(int enterAnim, int exitAnim)实现的. 这个方法是API Level 5 加入的. 这个方法在startActivity(Intent) or finish()之后被调用,指定接下来的这个转场动画. 方法的第一个参数:enterAnim,是新的Activity的进入动画的resource ID: 第二