当前位置: 代码迷 >> Android >> Android中的卡通
  详细解决方案

Android中的卡通

热度:45   发布时间:2016-04-27 23:32:53.0
Android中的动画

Animation 概述

安装中的动画分为三种:补间动画(Tween Animation),帧动画(Frame Animation)和属性动画(Property Animation)。在有些资料中补间动画又被称为View Animation,帧动画又被称为drawable Animation(至少我个人感觉它们应该是一个意思,如果有不同看法,欢迎留言告知)。其中属性动画是Android3.0(API Level 11)之后才出现的。

Tween Animation 补间动画

补间动画有四个主要的实现,分别是 Translate Animation,Scale Animation , Rotate Animation , Alpha Animation 。

Transparent Animation:平移动画

     主要控制位置变换的动画实现类,常使用TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)来构造;

    fromXDelta:动画开始的X坐标;
    toXDelta:动画结束的X坐标;
    fromYDelta:动画开始的Y坐标;
    toYDelta:动画结束的Y坐标;

Scale Animation:缩放动画

    主要控制尺度变化的动画类,常使用ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)来构造;
 
    fromX:动画开始X坐标上的伸缩尺度;
    toX:动画结束X坐标上的伸缩尺度; 
    fromY:动画开始Y坐标上的伸缩尺度;
    toY:动画结束Y坐标上的伸缩尺度;
    pivotXType:X坐标上的伸缩模式,取值有:Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_PARENT;
    pivotXValue:X坐标上的伸缩值;
    pivotYType:Y坐标上的伸缩模式,取值有:Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_PARENT;
    pivotYValue:Y坐标上的伸缩值;

Rotate Animation :旋转动画

    主要控制旋转的动画实现类,常使用RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)来构造;
 
    fromDegrees:旋转开始角度;
    toDegrees:旋转结束角度;
    pivotXType, pivotXValue, pivotYType, pivotYValue与尺度变化动画ScaleAnimation类似

Alpha Animation :透明度渐变动画

    主要控制透明度变化动画类,常使用AlphaAnimation(float fromAlpha, float toAlpha)来构造;
    fromAlpha:动画开始时的透明度(取值范围为0.0到1.0);
    toAlpha:动画结束时的透明度;
 

补间动画的Demo

代码中new动画的方式

界面布局如下:

 

layout中的布局文件 activity_main.xml

<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=".MainActivity" ><LinearLayout     android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical"    >    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal" >        <Button            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:onClick="click1"            android:text="alpha" />        <Button            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:onClick="click2"            android:text="scale" />        <Button            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:onClick="click3"            android:text="rotate" />        <Button            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:onClick="click4"            android:text="translate" />    </LinearLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal" >        <Button            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:onClick="click5"            android:text="一起执行" />    </LinearLayout></LinearLayout>    <ImageView        android:id="@+id/iv"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:src="@drawable/ic_launcher" /></RelativeLayout>

MainActivity代码如下 (采用直接new的方式)       

public class MainActivity extends Activity {	private ImageView iv;		@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);		//用来执行动画 		iv = (ImageView) findViewById(R.id.iv);		//给iv设置一个点击事件		iv.setOnClickListener(new OnClickListener() {			@Override			public void onClick(View v) {			//用来证明该图片的真实属性没有改变(区别于属性动画)				Toast.makeText(getApplicationContext(), "你点不到我", 1).show();			}		});	}	// 点击按钮 执行透明动画	public void click1(View v) {		//1.0 完全不透明     0.0完全透明		AlphaAnimation aa = new AlphaAnimation(1.0f, 0.0f);		aa.setDuration(2000);//设置动画执行时长		aa.setRepeatCount(1);//设置动画执行的重复次数 		aa.setRepeatMode(Animation.REVERSE); //设置动画执行的模式		//让iv执行动画		iv.startAnimation(aa);		}	// 点击按钮 执行缩放动画    缩放包括放大 缩小 	public void click2(View v) {		ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);		sa.setDuration(2000);//设置动画执行时长		sa.setRepeatCount(1);//设置动画执行的重复次数 		sa.setRepeatMode(Animation.REVERSE); //设置动画执行的模式		//让iv执行动画		iv.startAnimation(sa);	}	// 点击按钮 执行旋转动画	public void click3(View v) {		//创建旋转动画		//RotateAnimation ra = new RotateAnimation(0, 360);		RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);				ra.setDuration(2000);//设置动画执行时长		ra.setRepeatCount(1);//设置动画执行的重复次数 		ra.setRepeatMode(Animation.REVERSE); //设置动画执行的模式		//让iv执行动画		iv.startAnimation(ra);	}	// 点击按钮 执行位移动画	public void click4(View v) {		TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0.2f);		ta.setDuration(2000);//设置动画执行时长		//ta.setRepeatCount(1);//设置动画执行的重复次数 //		ta.setRepeatMode(Animation.REVERSE); //设置动画执行的模式				ta.setFillAfter(true);//动画结束后   动画停留在结束的位置上 				//让iv执行动画		iv.startAnimation(ta);			}		//让动画一起执行(动画集)	public void click5(View v){		//创建动画的集合		AnimationSet set = new AnimationSet(false);				AlphaAnimation aa = new AlphaAnimation(1.0f, 0.0f);		aa.setDuration(2000);//设置动画执行时长		aa.setRepeatCount(1);//设置动画执行的重复次数 		aa.setRepeatMode(Animation.REVERSE); //设置动画执行的模式				ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);		sa.setDuration(2000);//设置动画执行时长		sa.setRepeatCount(1);//设置动画执行的重复次数 		sa.setRepeatMode(Animation.REVERSE); //设置动画执行的模式			    RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);				ra.setDuration(2000);//设置动画执行时长		ra.setRepeatCount(1);//设置动画执行的重复次数 		ra.setRepeatMode(Animation.REVERSE); //设置动画执行的模式				//添加几个动画效果		set.addAnimation(aa);		set.addAnimation(sa);		set.addAnimation(ra);				//执行动画		iv.startAnimation(set);	}	}


使用xml文件的方式

创建xml文件

对应的xml内容分别为

aplha.xml

<?xml version="1.0" encoding="utf-8"?><alpha xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="2000"    android:fromAlpha="1.0"    android:repeatCount="1"    android:repeatMode="reverse"    android:toAlpha="0" ></alpha>

rotate.xml

<?xml version="1.0" encoding="utf-8"?><rotate    android:fromDegrees="0"    android:toDegrees="360"    android:pivotX="50%"    android:pivotY="50%"    android:repeatMode="reverse"    android:repeatCount="1"    android:duration="2000"    xmlns:android="http://schemas.android.com/apk/res/android">    </rotate>

scale.xml

<?xml version="1.0" encoding="utf-8"?><scale    android:fromXScale="0.2"    android:toXScale="2.0"    android:fromYScale="0.2"    android:toYScale="2.0"        android:pivotX="50%"    android:pivotY="50%"    android:repeatMode="reverse"    android:repeatCount="1"    android:duration="2000"    xmlns:android="http://schemas.android.com/apk/res/android">    </scale>

set.xml

<?xml version="1.0" encoding="utf-8"?><set>    <alpha xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="2000"    android:fromAlpha="1.0"    android:repeatCount="1"    android:repeatMode="reverse"    android:toAlpha="0" ></alpha>    <scale    android:fromXScale="0.2"    android:toXScale="2.0"    android:fromYScale="0.2"    android:toYScale="2.0"        android:pivotX="50%"    android:pivotY="50%"    android:repeatMode="reverse"    android:repeatCount="1"    android:duration="2000"    xmlns:android="http://schemas.android.com/apk/res/android">    </scale>    <rotate    android:fromDegrees="0"    android:toDegrees="360"    android:pivotX="50%"    android:pivotY="50%"    android:repeatMode="reverse"    android:repeatCount="1"    android:duration="2000"    xmlns:android="http://schemas.android.com/apk/res/android">    </rotate></set>

translate.xml

<?xml version="1.0" encoding="utf-8"?><translate    android:fromXDelta="0%p"    android:toXDelta="0%p"    android:fromYDelta="0%p"    android:toYDelta="20%p"    android:fillAfter="true"    android:repeatMode="reverse"    android:duration="2000"    xmlns:android="http://schemas.android.com/apk/res/android">    </translate>


layout中的布局文件 activity_main.xml (和上面new方式的大致一样,所以省略)

MainActivity.java中的 代码如下

public class MainActivity extends Activity {	private ImageView iv;	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);				//用来执行动画 		iv = (ImageView) findViewById(R.id.iv);		//给iv设置一个点击事件		iv.setOnClickListener(new OnClickListener() {						@Override			public void onClick(View v) {				Toast.makeText(getApplicationContext(), "你点不到我", 1).show();			}		});			}	// 点击按钮 执行透明动画	public void click1(View v) {		//1.0 完全不透明     0.0完全透明		Animation aa = AnimationUtils.loadAnimation(this, R.anim.aplha);		iv.startAnimation(aa);		}	// 点击按钮 执行缩放动画    缩放包括放大 缩小 	public void click2(View v) {		Animation sa = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.scale);		iv.startAnimation(sa);	}	// 点击按钮 执行旋转动画	public void click3(View v) {		Animation ra = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.rotate);		//让iv执行动画		iv.startAnimation(ra);			}	// 点击按钮 执行位移动画	public void click4(View v) {		Animation ta = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.translate);		//让iv执行动画		iv.startAnimation(ta);	}		//让动画一起执行	public void click5(View v){		Animation set = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.set);		//执行动画		iv.startAnimation(set);	}}

 

Frame Animation 帧动画

Frame Animation在SDK中对应drawable Aniamtion 。通过切换一系列Drawable图片来模拟动画的效果。类似于.gif 动图,(ps:一般5~8张图片/秒,可以感受到动画效果)

01、帧动画在start()之前必须stop().因为在第一次动画之后,动画会停在最后一帧,这样动画只会执行一次。

02、不要在onCreate() 方法中调用动画的 start()方法,因为此时AnimationDrawable还没有完全跟Window相关联,如果想要界面显示时就开始动画的话,需要在onWindowFoucsChanged()中调用start()。

帧动画的Demo

效果图(不知道怎么添加啊!)

对应xml文件及图片存放

xml文件内容

<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android"    android:oneshot="false" >    <item        android:drawable="@drawable/girl_1"        android:duration="200"/>    <item        android:drawable="@drawable/girl_2"        android:duration="200"/>    <item        android:drawable="@drawable/girl_3"        android:duration="200"/>    <item        android:drawable="@drawable/girl_4"        android:duration="200"/>    <item        android:drawable="@drawable/girl_5"        android:duration="200"/>    <item        android:drawable="@drawable/girl_5"        android:duration="200"/>    <item        android:drawable="@drawable/girl_5"        android:duration="200"/>    <item        android:drawable="@drawable/girl_5"        android:duration="200"/>    <item        android:drawable="@drawable/girl_6"        android:duration="200"/>    <item        android:drawable="@drawable/girl_7"        android:duration="200"/>    <item        android:drawable="@drawable/girl_8"        android:duration="200"/>    <item        android:drawable="@drawable/girl_9"        android:duration="200"/>    <item        android:drawable="@drawable/girl_10"        android:duration="200"/>    <item        android:drawable="@drawable/girl_11"        android:duration="200"/></animation-list>

MainActivity.java文件代码如下

public class MainActivity extends Activity {	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);				//找到imageview 用来显示动画 		ImageView iv = (ImageView) findViewById(R.id.iv);	    //加载动画图片资源		iv.setBackgroundResource(R.drawable.myanim);				//获取我们要执行的资源 	    final AnimationDrawable anim = (AnimationDrawable) iv.getBackground();			    //兼容低版本手机的写法 	    new Thread() {			public void run() {				//此方法没有异常                  SystemClock.sleep(100);                 anim.start();//开始执行动画 			};		}.start();	}}

 Property Animation属性动画

由于Tween Animation不会改变资源的真实位置,所以有一些效果无法实现,比如:你希望View有一个颜色的切换动画;你希望可以使用3D旋转动画;你希望当动画停止时,View的位置就是当前的位置,这就是Property Animation产生的原因。属性动画不止可以应用于View,还可以应用于任何对象。Property Animation只是表示一个值在一段时间内的改变,当值改变时要做什么事情完全是你自己决定的。

属性动画的Demo

界面布局如下:

声明:这个Demo中代码创建动画和使用xml都存在

xml的创建和存放

oanimator.xml  代码

<?xml version="1.0" encoding="utf-8"?><animator xmlns:android="http://schemas.android.com/apk/res/android" >    <objectAnimator         android:propertyName="translationX"        android:duration="2000"        android:valueFrom="10"        android:valueTo="100"        ></objectAnimator></animator>

layout布局文件 activity_main.xml

<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=".MainActivity" >    <LinearLayout        android:id="@+id/ll"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal" >        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:onClick="translate"            android:text="平移" />        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:onClick="scale"            android:text="缩放" />        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:onClick="alpha"            android:text="透明" />        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:onClick="rotate"            android:text="旋转" />        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:onClick="fly"            android:text="set" />    </LinearLayout>    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@id/ll"        android:onClick="playxml"        android:text="播放xml定义的属性动画" />    <ImageView        android:id="@+id/iv"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:src="@drawable/ic_launcher" /></RelativeLayout>


MainActivity.java代码 如下(new方式和xml文件的方式都有)

public class MainActivity extends Activity {	private ImageView iv;	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);				iv = (ImageView) findViewById(R.id.iv);		iv.setOnClickListener(new OnClickListener() {						@Override			public void onClick(View v) {								Toast.makeText(MainActivity.this, "你点不到我", 0).show();			}		});	     	}	//位移动画	public void translate(View v){		//创建属性动画		/**		 * target 执行的目标  		 * propertyName 属性名字  The name of the property being animated.		 * float... values 可变参数 		 */		//从0,向右移动50,返回到20,....(相对于图片本身的位置)		ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX", 0, 50,20,100,60);		oa.setDuration(2000);		oa.start(); //开始动画			}	//缩放动画	public void scale(View v){		View view=new View(this);				ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "scaleY", 0.1f, 2, 1, 2);		oa.setDuration(2000);		oa.start();	}		//实现透明的效果 	public void alpha(View v){		ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "alpha", 0, 0.5f, 0, 1,0,1);		oa.setDuration(2000);		oa.start();	}		//实现旋转的效果	public void rotate(View v){		ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "rotation", 0, 180, 90, 360);//		ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "rotationY", 0, 180, 90, 360);		oa.setDuration(2000);		oa.start();	}			//一起飞 	public void fly(View v){		AnimatorSet as = new AnimatorSet();		ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX", 10, 50, 20, 100);		ObjectAnimator oa2 = ObjectAnimator.ofFloat(iv, "scaleY", 0.1f, 2, 1, 2);		ObjectAnimator oa3 = ObjectAnimator.ofFloat(iv, "alpha", 0, 0.5f, 0, 1);		ObjectAnimator oa4 = ObjectAnimator.ofFloat(iv, "rotationY", 0, 180, 90, 360);		as.setDuration(2000);		as.setTarget(iv);		//往集合中添加动画		//挨个飞		as.playSequentially(oa, oa2, oa3, oa4);//		一起飞//		as.playTogether(oa, oa2, oa3, oa4);		as.start();	}		//使用xml的方式创建属性动画	public void playxml(View v){		  		ObjectAnimator oa = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.oanimator);		//设置执行目标		oa.setTarget(iv);		oa.start();//开始执行	}}

 

动画的使用

Android 动画可以在 Java 代码中使用,也可以在 XML文件中配置之后,调用res下的资源。

☆ 在代码中使用时,直接 new 所需要的动画;

☆ 在 XML 中使用时,在创建xml文件及存放时要区别对待:

     补间动画: 在 res 下新建 anim(名字文件名必须是anim)文件夹 ,创建对应的 xml 文件(文件名自定义)

     帧动画:  把所需图片和xml文件放在drawable下即可

     属性动画:在 res 下新建 animator(名字文件名必须是animtor)文件夹 ,创建对应的 xml 文件(文件名自定义)

为了区分Property animation和View animation(我认为就是指补间动画)的资源文件,从Android 3.1开始,Property animation的xml文件存在res/animator/目录下(View animation的存在res/anim/目录下), animator这个名是可选的。但是如果你想要使用Eclipse ADT plugin (ADT 11.0.0+)的布局编辑器,你就必须使用res/animator/目录,因为ADT只在该目录下寻找property animation的资源文件。

 常用的方法

·   setDuration 设置动画的执行时间

·   setRepeatCount设置动画的重复次数

·   setRepeatMode 指定重复的模式(如:反转)

·   setFillAfter 指示动画指定完毕之后控件的状态是否停留在动画停止的时候

·   setAnimationListener 设置动画的事件监听器

·   setStartOffset 设置动画的延迟时间

·   startAnimation(Animation a) 让View执行某动画

 

动画集

    当多个动画效果作用于一个控件时,使用动画集合。在代码中使用时AnimationSet,在Xml文件中使用是<set>节点。在上文的demo中有体现。

小结

在实际开发中,比较常用的是补间动画和属性动画,在使用时首先考虑该view的真实属性是否需要改变。而帧动画只会在某些特殊连续的效果上才会使用,比如要自己做一个gif的效果。其中使用平移,缩放,旋转和明暗渐变组合起来就可以实现很多效果,而且上文中还没有提到一个东西 :插值器。在后面需要做一些比较炫的效果时我们再来详细研究一下。

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案