您的位置:首页 > 移动开发 > Android开发

【Android】两种动画介绍(Tween动画、Frame动画)

2016-09-28 15:45 387 查看
Android中的动画类型有两种,一种是Tween动画、还有一种是Frame动画。Tween动画,这种实现方式可以使视图组件移动、放大、缩小以及产生透明度的变化;另一种Frame动画,传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影。下面将一一详细介绍:

本博客参考自网络,结合自己一点理解,实为学习之用,不为其他目的。

一,Tween动画

又称“补间动画”、“中间动画”,最早接触Tween类是在学习Flash时候,使用ActionScript做动画的时候,使用过类Tween。

Tween动画主要的功能是在绘制动画前设置动画绘制的轨迹,包括时间,
位置 ,等等。但是Tween动画的缺点是它只能设置起始点与结束点的两帧,中间过程全部由系统帮我们完成。所以在帧数比较多的游戏开发中是不太会用到它的。


Tween一共提供了4中动画的效果

Scale:缩放动画

Rotate:旋转动画

Translate:移动动画

Alpha::透明渐变动画

Tween与Frame动画类似都需要在res\anim路径下创建动画的 布局文件

1)Scale动画



import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.animation.Animation;

import android.view.animation.AnimationUtils;

import android.widget.Button;

import android.widget.ImageView;

public class ScaleActivity extends Activity {

Button mButton0 = null;//缩小动画

Button mButton1 = null;//放大动画

ImageView mImageView = null; //显示动画

Animation mLitteAnimation = null; //缩小动画

Animation mBigAnimation = null; //放大动画

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.scale);

mImageView = (ImageView)findViewById(R.id.imageView);

/**加载缩小与放大动画**/

mLitteAnimation = AnimationUtils.loadAnimation(this, R.anim.scalelitte);

mBigAnimation = AnimationUtils.loadAnimation(this, R.anim.scalebig);

mButton0 = (Button)findViewById(R.id.button0);

mButton0.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View arg0) {

/**播放缩小动画**/

mImageView.startAnimation(mLitteAnimation);

}

});

mButton1 = (Button)findViewById(R.id.button1);

mButton1.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View arg0) {

/**播放放大动画**/

mImageView.startAnimation(mBigAnimation);

}

});

}

}

<scale>标签为缩放节点

android:fromXscale="1.0" 表示开始时X轴缩放比例为 1.0 (原图大小 * 1.0 为原图大小)

android:toXscale="0.0" 表示结束时X轴缩放比例为0.0(原图大小 *0.0 为缩小到看不见)

android:fromYscale="1.0" 表示开始时Y轴缩放比例为 1.0 (原图大小 * 1.0 为原图大小)

android:toYscale="0.0" 表示结束时Y轴缩放比例为0.0(原图大小 *0.0 为缩小的看不到了)

android:pivotX="50%" X轴缩放的位置为中心点

android:pivotY="50%" Y轴缩放的位置为中心点

android:duration="2000" 动画播放时间 这里是2000毫秒也就是2秒

/anim/scalelitte.xml

<?xml version="1.0" encoding="utf-8"?>

<scale

xmlns:android="http://schemas.android.com/apk/res/android"

android:fromXScale="0.0"

android:toXScale="1.0"

android:fromYScale="0.0"

android:toYScale="1.0"

android:pivotX="50%"

android:pivotY="50%"

android:duration="2000">

</scale>

/anim/scalebig.xml

<?xml version="1.0" encoding="utf-8"?>

<scale xmlns:android="http://schemas.android.com/apk/res/android"

android:fromXScale="1.0"

android:toXScale="0.0"

android:fromYScale="1.0"

android:toYScale="0.0"

android:pivotX="50%"

android:pivotY="50%"

android:duration="2000">

</scale>

如果在代码中,加载动画,而不用xml配置动画

mLitteAnimation = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f,

Animation.RELATIVE_TO_SELF, 0.5f,

Animation.RELATIVE_TO_SELF, 0.5f);

mLitteAnimation.setDuration(2000);

2)Rotate旋转动画






import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.animation.Animation;

import android.view.animation.AnimationUtils;

import android.widget.Button;

import android.widget.ImageView;

public class RotateActivity extends Activity {

/**向左旋转动画按钮**/

Button mButton0 = null;

/**向右旋转动画按钮**/

Button mButton1 = null;

/**显示动画的ImageView**/

ImageView mImageView = null;

/**向左旋转动画**/

Animation mLeftAnimation = null;

/**向右旋转动画**/

Animation mRightAnimation = null;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.retate);

/**拿到ImageView对象**/

mImageView = (ImageView)findViewById(R.id.imageView);

/**加载向左与向右旋转动画**/

mLeftAnimation = AnimationUtils.loadAnimation(this, R.anim.retateleft);

mRightAnimation = AnimationUtils.loadAnimation(this, R.anim.retateright);

mButton0 = (Button)findViewById(R.id.button0);

mButton0.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View arg0) {

/**播放向左旋转动画**/

mImageView.startAnimation(mLeftAnimation);

}

});

mButton1 = (Button)findViewById(R.id.button1);

mButton1.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View arg0) {

/**播放向右旋转动画**/

mImageView.startAnimation(mRightAnimation);

}

});

}

}

<rotate>标签为旋转节点

Tween一共为我们提供了3种动画渲染模式。

android:interpolator="@android:anim/accelerate_interpolator" 设置动画渲染器为加速动画(动画播放中越来越快)

android:interpolator="@android:anim/decelerate_interpolator" 设置动画渲染器为减速动画(动画播放中越来越慢)

android:interpolator="@android:anim/accelerate_decelerate_interpolator" 设置动画渲染器为先加速在减速(开始速度最快 逐渐减慢)

如果不写的话 默认为匀速运动

android:fromDegrees="+360"设置动画开始的角度

android:toDegrees="0"设置动画结束的角度

这个动画布局设置动画将向左做360度旋转加速运动。

/anim/retateleft.xml

<?xml version="1.0" encoding="utf-8"?>

<rotate xmlns:android="http://schemas.android.com/apk/res/android"

android:interpolator="@android:anim/accelerate_interpolator"

android:fromDegrees="+360"

android:toDegrees="0"

android:pivotX="50%"

android:pivotY="50%"

android:duration="2000"

/>

/anim/retateright.xml

<?xml version="1.0" encoding="utf-8"?>

<rotate xmlns:android="http://schemas.android.com/apk/res/android"

android:interpolator="@android:anim/decelerate_interpolator"

android:fromDegrees="0"

android:toDegrees="+360"

android:pivotX="50%"

android:pivotY="50%"

android:duration="2000"

/>

如果在代码中加载动画,而不用xml配置,代码如下

mLeftAnimation = new RotateAnimation(360.0f, 0.0f,

Animation.RELATIVE_TO_SELF, 0.5f,

Animation.RELATIVE_TO_SELF, 0.5f);

mLeftAnimation.setDuration(2000);

3)Translate移动动画

import android.app.Activity;

23ff7

import android.os.Bundle;

import android.view.animation.Animation;

import android.view.animation.AnimationUtils;

import android.widget.ImageView;

public class TranslateActivity extends Activity {

/**显示动画的ImageView**/

ImageView mImageView = null;

/**移动动画**/

Animation mAnimation = null;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.translate);

/**拿到ImageView对象**/

mImageView = (ImageView)findViewById(R.id.imageView);

/**加载移动动画**/

mAnimation = AnimationUtils.loadAnimation(this, R.anim.translate);

/**播放移动动画**/

mImageView.startAnimation(mAnimation);

}

}

/layout/translate.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<ImageView

android:id="@+id/imageView"

android:src="@drawable/images"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

/>

</LinearLayout>

/anim/translate.xml

<?xml version="1.0" encoding="utf-8"?>

<translate xmlns:android="http://schemas.android.com/apk/res/android"

android:fromXDelta="0"

android:toXDelta="320"

android:fromYDelta="0"

android:toYDelta="480"

android:duration="2000"

android:repeatCount="infinite"

/>

说明:

<?xml version="1.0" encoding="utf-8"?>

<translate xmlns:android="http://schemas.android.com/apk/res/android"

android:fromXDelta="0"

android:toXDelta="320"

android:fromYDelta="0"

android:toYDelta="480"

android:duration="2000"

android:repeatCount="infinite"

/>

代码中加载动画:

mAnimation = new TranslateAnimation(0, 320, 0, 480);

mAnimation.setDuration(2000);

4 )Alpha:透明渐变动画

import android.app.Activity;

import android.os.Bundle;

import android.view.animation.Animation;

import android.view.animation.AnimationUtils;

import android.widget.ImageView;

public class AlphaActivity extends Activity {

/**显示动画的ImageView**/

ImageView mImageView = null;

/**透明动画**/

Animation mAnimation = null;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.translate);

/**拿到ImageView对象**/

mImageView = (ImageView)findViewById(R.id.imageView);

/**加载透明动画**/

mAnimation = AnimationUtils.loadAnimation(this, R.anim.alpha);

/**播放透明动画**/

mImageView.startAnimation(mAnimation);

}

}

/anim/alpha.xml

<?xml version="1.0" encoding="utf-8"?>

<alpha xmlns:android="http://schemas.android.com/apk/res/android"

android:fromAlpha="1.0"

android:toAlpha="0.0"

android:repeatCount="infinite"

android:duration="2000">

</alpha>

说明:

<alpha>标签为alpha透明度节点

android:fromAlpha="1.0" 设置动画起始透明度为1.0 表示完全不透明

android:toAlpha="0.0"设置动画结束透明度为0.0 表示完全透明

也就是说alpha的取值范围为0.0 - 1.0 之间

手动加载动画:

mAnimation = new AlphaAnimation(1.0f, 0.0f);

mAnimation.setDuration(2000);

5)综合动画

可以将上面介绍的4种动画设置在一起同时进行播放,那么就须要使用<set>标签将所有须要播放的动画放在一起。

这个动画布局设置动画同时播放移动、渐变、旋转。


import android.app.Activity;

import android.os.Bundle;

import android.view.animation.Animation;

import android.view.animation.AnimationUtils;

import android.widget.ImageView;

public class AllActivity extends Activity {

ImageView mImageView = null;

Animation mAnimation = null;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.translate);

mImageView = (ImageView)findViewById(R.id.imageView);

mAnimation = AnimationUtils.loadAnimation(this, R.anim.all);

mImageView.startAnimation(mAnimation);

}

}

/anim/all.xml

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">

<rotate

android:interpolator="@android:anim/accelerate_interpolator"

android:fromDegrees="+360"

android:toDegrees="0"

android:pivotX="50%"

android:pivotY="50%"

android:duration="2000"

android:repeatCount="infinite"

/>

<alpha android:fromAlpha="1.0"

android:toAlpha="0.0"

android:repeatCount="infinite"

android:duration="2000">

</alpha>

<translate

android:fromXDelta="0"

android:toXDelta="320"

android:fromYDelta="0"

android:toYDelta="480"

android:duration="2000"

android:repeatCount="infinite"

/>

</set>

二,AnimationDrable实现Frame动画(设计游戏专用,嘎嘎嘎)感谢宣教主分享



import android.app.Activity;

import android.graphics.drawable.AnimationDrawable;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ImageView;

import android.widget.RadioButton;

import android.widget.RadioGroup;

import android.widget.SeekBar;

import android.widget.SeekBar.OnSeekBarChangeListener;

public class SimpleActivity extends Activity {

/**播放动画按钮**/

Button button0 = null;

/**停止动画按钮**/

Button button1 = null;

/**设置动画循环选择框**/

RadioButton radioButton0= null;

RadioButton radioButton1= null;

RadioGroup radioGroup = null;

/**拖动图片修改Alpha值**/

SeekBar seekbar = null;

/**绘制动画View**/

ImageView imageView = null;

/**绘制动画对象**/

AnimationDrawable animationDrawable = null;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.simple);

/**拿到ImageView对象**/

imageView = (ImageView)findViewById(R.id.imageView);

/**通过ImageView对象拿到背景显示的AnimationDrawable**/

animationDrawable = (AnimationDrawable) imageView.getBackground();

/**开始播放动画**/

button0 = (Button)findViewById(R.id.button0);

button0.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View arg0) {

/**播放动画**/

if(!animationDrawable.isRunning()) {

animationDrawable.start();

}

}

});

/**停止播放动画**/

button1 = (Button)findViewById(R.id.button1);

button1.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View arg0) {

/**停止动画**/

if(animationDrawable.isRunning()) {

animationDrawable.stop();

}

}

});

/**单次播放**/

radioButton0 = (RadioButton)findViewById(R.id.checkbox0);

/**循环播放**/

radioButton1 = (RadioButton)findViewById(R.id.checkbox1);

/**单选列表组**/

radioGroup = (RadioGroup)findViewById(R.id.radiogroup);

radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

@Override

public void onCheckedChanged(RadioGroup radioGroup, int checkID) {

if(checkID == radioButton0.getId()) {

//设置单次播放

animationDrawable.setOneShot(true);

}else if (checkID == radioButton1.getId()) {

//设置循环播放

animationDrawable.setOneShot(false);

}

//发生改变后让动画重新播放

animationDrawable.stop();

animationDrawable.start();

}

});

/**监听的进度条修改透明度**/

seekbar = (SeekBar)findViewById(R.id.seekBar);

seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

@Override

public void onStopTrackingTouch(SeekBar seekBar) {

}

@Override

public void onStartTrackingTouch(SeekBar seekBar) {

}

@Override

public void onProgressChanged(SeekBar seekBar, int progress, boolean frameTouch) {

/**设置动画Alpha值**/

animationDrawable.setAlpha(progress);

/**通知imageView 刷新屏幕**/

imageView.postInvalidate();

}

});

}

}

/layout/simple.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<LinearLayout

android:orientation="horizontal"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

>

<Button

android:id="@+id/button0"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="播放动画"

/>

<Button

android:id="@+id/button1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="停止动画"

/>

</LinearLayout>

<RadioGroup android:id="@+id/radiogroup"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="horizontal">

<RadioButton

android:id="@+id/checkbox0"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:checked="true"

android:text="单次播放"

/>

<RadioButton

android:id="@+id/checkbox1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="循环播放"

/>

</RadioGroup>

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="拖动进度条修改透明度(0 - 255)之间"

/>

<SeekBar

android:id="@+id/seekBar"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:max="256"

android:progress="256"/>

<ImageView

android:id="@+id/imageView"

android:background="@anim/animation"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

/>

</LinearLayout>

控制帧播放的/anim/animation.xml

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">

<item android:drawable="@drawable/a" android:duration="100" />

<item android:drawable="@drawable/b" android:duration="100" />

<item android:drawable="@drawable/c" android:duration="100" />

<item android:drawable="@drawable/d" android:duration="100" />

<item android:drawable="@drawable/e" android:duration="100" />

<item android:drawable="@drawable/f" android:duration="100" />

<item android:drawable="@drawable/g" android:duration="100" />

<item android:drawable="@drawable/h" android:duration="100" />

<item android:drawable="@drawable/i" android:duration="100" />

<item android:drawable="@drawable/j" android:duration="100" />

</animation-list>

看看内容应该是很好理解的,<animation-list>为动画的总标签,这里面放着帧动画 <item>标签,也就是说若干<item>标签的帧 组合在一起就是帧动画了。<animation-list > 标签中android:oneshot="false"
这是一个非常重要的属性,默认为false 表示 动画循环播放, 如果这里写true 则表示动画只播发一次。 <item>标签中记录着每一帧的信息android:drawable="@drawable/a"表示这一帧用的图片为"a",下面以此类推。 android:duration="100" 表示这一帧持续100毫秒,可以根据这个值来调节动画播放的速度。


这是一个比较简单的布局文件,应该都能看懂吧。 我主要说一下 最后的这个 ImageView, 它就是用来显示我们的动画。 这里使用android:background="@anim/animation"设置这个ImageView现实的背景为一个动画,动画资源的路径为res/anim/animation.xml
,当然 设置background同样也可以在代码中设置。


imageView.setBackgroundResource(R.anim.animation);



通过getBackground方法就可以拿到这个animationDrawable对象。


/**拿到ImageView对象**/

imageView = (ImageView)findViewById(R.id.imageView);

/**通过ImageView对象拿到背景显示的AnimationDrawable**/

animationDrawable = (AnimationDrawable) imageView.getBackground();



AnimationDrawable 就是用来控制这个帧动画,这个类中提供了很多方法。

animationDrawable.start(); 开始这个动画

animationDrawable.stop(); 结束这个动画

animationDrawable.setAlpha(100);设置动画的透明度, 取值范围(0 - 255)

animationDrawable.setOneShot(true); 设置单次播放

animationDrawable.setOneShot(false); 设置循环播放

animationDrawable.isRunning(); 判断动画是否正在播放

animationDrawable.getNumberOfFrames(); 得到动画的帧数。


宣教主警戒:拖动进度条设置Alpha值的时候 一定要使用 imageView.postInvalidate(); 方法来通知UI线程重绘屏幕中的imageView 否则会看不到透明的效果 。这里切记切记~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息