Android Animation学习 实现 IOS 滤镜退出动画
IOS的用户体验做的很好,其中一点很重要的地方就是动画效果。
最近在学习Android的Animation,简单实现了一个IOS相机滤镜退出的动画:
布局文件:activity_animation_demo.xml 布局未考虑各个分辨率,只是为了实现动画逻辑,(代码测试是在720P分辨率的手机上)
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context="com.example.andanimationdemo.AnimationDemoActivity" >
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="50dp"
- android:layout_marginLeft="25px"
- android:layout_marginRight="25px"
- >
- <LinearLayout
- android:id="@+id/rootLinearLayout"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- >
- <LinearLayout
- android:id="@+id/firstLinearLayout"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <Button
- android:id="@+id/Button_1"
- android:layout_width="200px"
- android:layout_height="200px"
- android:background="@android:color/holo_blue_bright"/>
- <Button
- android:id="@+id/Button_2"
- android:layout_width="200px"
- android:layout_height="200px"
- android:layout_marginLeft="35px"
- android:background="@android:color/holo_green_light"/>
- <Button
- android:layout_marginLeft="35px"
- android:id="@+id/Button_3"
- android:layout_width="200px"
- android:layout_height="200px"
- android:background="@android:color/black"/>
- </LinearLayout>
- <LinearLayout
- android:id="@+id/SencondLinearLayout"
- android:layout_marginTop="35px"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <Button
- android:id="@+id/Button_4"
- android:layout_width="200px"
- android:layout_height="200px"
- android:background="@android:color/holo_orange_dark"/>
- <Button
- android:id="@+id/Button_5"
- android:layout_width="200px"
- android:layout_height="200px"
- android:layout_marginLeft="35px"
- android:background="@android:color/holo_red_light"/>
- <Button
- android:layout_marginLeft="35px"
- android:id="@+id/Button_6"
- android:layout_width="200px"
- android:layout_height="200px"
- android:background="@android:color/darker_gray"/>
- </LinearLayout>
- <LinearLayout
- android:id="@+id/ThirdLinearLayout"
- android:layout_marginTop="35px"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <Button
- android:id="@+id/Button_7"
- android:layout_width="200px"
- android:layout_height="200px"
- android:background="@android:color/holo_green_light"/>
- <Button
- android:id="@+id/Button_8"
- android:layout_width="200px"
- android:layout_height="200px"
- android:layout_marginLeft="35px"
- android:background="@android:color/holo_orange_light"/>
- <Button
- android:layout_marginLeft="35px"
- android:id="@+id/Button_9"
- android:layout_width="200px"
- android:layout_height="200px"
- android:background="@android:color/holo_blue_light"/>
- </LinearLayout>
- </LinearLayout>
- </FrameLayout>
- <Button
- android:id="@+id/Reset"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_alignParentBottom="true"
- android:layout_marginRight="40dp"
- android:layout_marginBottom="40dp"
- android:text="Reset"></Button>
- </RelativeLayout>
AnimationDemoActivity.java
- package com.example.andanimationdemo;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.animation.Animation;
- import android.view.animation.Animation.AnimationListener;
- import android.view.animation.ScaleAnimation;
- import android.widget.Button;
- import android.widget.LinearLayout;
- public class AnimationDemoActivity extends Activity implements OnClickListener{
- private static final String TAG = "AnimationDemo";
- LinearLayout rootLinearLayout;
- Button resetButton;
- int mCurrentClickButtonId = -1;
- int[] ButtonID = new int[] {
- R.id.Button_1,R.id.Button_2,R.id.Button_3,
- R.id.Button_4,R.id.Button_5,R.id.Button_6,
- R.id.Button_7,R.id.Button_8,R.id.Button_9
- };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_animation_demo);
- rootLinearLayout = (LinearLayout) findViewById(R.id.rootLinearLayout);
- resetButton = (Button) findViewById(R.id.Reset);
- setButtonListener();
- }
- private void setButtonListener() {
- for (int i = 0; i < ButtonID.length; i++) {
- rootLinearLayout.findViewById(ButtonID[i]).setOnClickListener(this);
- }
- resetButton.setOnClickListener(this);
- }
- /**
- * 点击某个按钮后,开始放大动画
- * 这里提供的是一个思路,并不局限于当前布局,放大倍数,通过哪个点放大,都可以计算出来。
- */
- boolean onAnimationRunning = false;
- public void onAnimationButtonClick() {
- Log.d(TAG, "onAnimationButtonClick");
- int[] position = new int[2];
- int[] ButtonPosition = new int[2];
- Button AnimaitonBtton = (Button) rootLinearLayout.findViewById(ButtonID[mCurrentClickButtonId - 1]);
- rootLinearLayout.getLocationInWindow(position);
- AnimaitonBtton.getLocationInWindow(ButtonPosition);
- int rootWidth = rootLinearLayout.getWidth();
- int rootHeight = rootLinearLayout.getHeight();
- int ButtonWidth = AnimaitonBtton.getWidth();
- int ButtonHeight = AnimaitonBtton.getHeight();
- /**
- * 计算 scale factor
- */
- float widthRate = (float)rootWidth/ButtonWidth;
- float heightRate = (float)rootHeight/ButtonHeight;
- /**
- * 计算放大的中心点
- */
- float PointA = (ButtonPosition[0] - position[0]) * widthRate / (widthRate - 1);
- float PointB = (ButtonPosition[1] - position[1]) * heightRate / (heightRate - 1);
- onAnimationRunning = true;
- ScaleAnimation mScaleAnimation = new ScaleAnimation(1.0f, widthRate, 1.0f, heightRate,PointA,PointB);
- mScaleAnimation.setDuration(2000);
- mScaleAnimation.setFillAfter(true);
- mScaleAnimation.setAnimationListener(new AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
- }
- @Override
- public void onAnimationRepeat(Animation animation) {
- }
- @Override
- public void onAnimationEnd(Animation animation) {
- Log.d(TAG,"onAnimationEnd");
- onAnimationRunning = false;
- for (int i = 0; i< ButtonID.length; i++) {
- rootLinearLayout.findViewById(ButtonID[i]).setEnabled(false);
- }
- }
- });
- rootLinearLayout.startAnimation(mScaleAnimation);
- }
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Log.d(TAG, "onClick :" + v.getId());
- if (onAnimationRunning) {
- Log.d(TAG, "onAnimationRunning = true");
- return;
- }
- switch (v.getId()) {
- case R.id.Button_1:
- mCurrentClickButtonId = 1;
- onAnimationButtonClick();
- break;
- case R.id.Button_2:
- mCurrentClickButtonId = 2;
- onAnimationButtonClick();
- break;
- case R.id.Button_3:
- mCurrentClickButtonId = 3;
- onAnimationButtonClick();
- break;
- case R.id.Button_4:
- mCurrentClickButtonId = 4;
- onAnimationButtonClick();
- break;
- case R.id.Button_5:
- mCurrentClickButtonId = 5;
- onAnimationButtonClick();
- break;
- case R.id.Button_6:
- mCurrentClickButtonId = 6;
- onAnimationButtonClick();
- break;
- case R.id.Button_7:
- mCurrentClickButtonId = 7;
- onAnimationButtonClick();
- break;
- case R.id.Button_8:
- mCurrentClickButtonId = 8;
- onAnimationButtonClick();
- break;
- case R.id.Button_9:
- mCurrentClickButtonId = 9;
- onAnimationButtonClick();
- break;
- case R.id.Reset:
- mCurrentClickButtonId = -1;
- rootLinearLayout.clearAnimation();
- rootLinearLayout.postInvalidate();
- for (int i = 0; i< ButtonID.length; i++) {
- rootLinearLayout.findViewById(ButtonID[i]).setEnabled(true);
- }
- break;
- default:
- break;
- }
- }
- }
点击某个Button后,可以通过它所在的位置坐标,以及父布局所在的位置坐标,计算出通过哪个点放大。
实现的效果如下图:
如有什么不对的地方,还望大神指正。
Android Animation学习 实现 IOS 滤镜退出动画的更多相关文章
- Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition
Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition Property animation系统还提供了对ViewGroup中的View改变 ...
- Android Animation学习(四) ApiDemos解析:多属性动画
Android Animation学习(四) ApiDemos解析:多属性动画 如果想同时改变多个属性,根据前面所学的,比较显而易见的一种思路是构造多个对象Animator , ( Animator可 ...
- Android Animation学习(三) ApiDemos解析:XML动画文件的使用
Android Animation学习(三) ApiDemos解析:XML动画文件的使用 可以用XML文件来定义Animation. 文件必须有一个唯一的根节点: <set>, <o ...
- Android Animation学习(六) View Animation介绍
Android Animation学习(六) View Animation介绍 View Animation View animation系统可以用来执行View上的Tween animation和F ...
- Android Animation学习(二) ApiDemos解析:基本Animators使用
Android Animation学习(二) ApiDemos解析:基本Animatiors使用 Animator类提供了创建动画的基本结构,但是一般使用的是它的子类: ValueAnimator.O ...
- Android Animation学习(一) Property Animation原理介绍和API简介
Android Animation学习(一) Property Animation介绍 Android Animation Android framework提供了两种动画系统: property a ...
- Android Animation学习(二) ApiDemos解析:基本Animatiors使用
Animator类提供了创建动画的基本结构,但是一般使用的是它的子类: ValueAnimator.ObjectAnimator.AnimatorSet ApiDemos中Animation部分是单独 ...
- Android Animation学习笔记
原文地址: http://www.cnblogs.com/feisky/archive/2010/01/11/1644482.html 关于动画的实现,Android提供了Animation,在And ...
- Android animation学习笔记之view/drawable animation
前一章中总结了android animation中property animation的知识和用法,这一章总结View animation和Drawable animation的有关知识: View ...
随机推荐
- 【 UVALive - 2197】Paint the Roads(上下界费用流)
Description In a country there are n cities connected by m one way roads. You can paint any of these ...
- 修改Delphi工具控件的默认字体
修改Delphi工具控件的默认字体: 注册表: Delphi 6: HKEY_CURRENT_USER\Software\Borland\Delphi\6.0Delphi 7: HKEY_ ...
- vs查看虚函数表和类内存布局
虚继承和虚基类 虚继承:在继承定义中包含了virtual关键字的继承关系: 虚基类:在虚继承体系中的通过virtual继承而来的基类,需要注意的是:class CSubClass : publ ...
- 全表扫描出现db file sequential read
SESSION 1执行 SQL> update test1 set id=1000; SESSION 2 : select * from test1 如果表上面有大量的行迁链接,会是单块读等待事 ...
- bzoj1391
很像最大权闭合子图的题目s向每个工作连边,流量为收益每个工序,由工作i向对应机器连边,流量为租用费每个机器向t连边,流量为购买费显然跑最小割,ans=总收益-mincut ; type node=re ...
- poj2954
水题,先用叉积求三角形面积然后求三边上的点(由公约数上点)a然后用pick定理S=a+b/2-1就可以求出内部的点数了 var x,y,xx,yy,a1,a2,a3,x1,x2,x3,y1,y2,y3 ...
- Java第一次写的流布局图形界面,留个纪念
package jisuanqi; import java.awt.*; public class MyFrame extends Frame{ //继承Frame类 public MyFrame() ...
- js遍历数组和遍历对象的区别
<script> //----------------for用来遍历数组对象-- var i,myArr = [1,2,3]; for (var i = 0; i < myArr.l ...
- 使用JavaScript扫描端口
<html> <title>端口扫描</title> <head></head><form><label fo ...
- c#基础语言编程-Path和Directory
引言 在程序常会对文件操作,在对文件操作中需要对文件路径的进行定位,在.Net中针对寻找文件提供两个静态类以供调用,Path和Directory. Path类 来自命名空间SYstem.IO,Path ...