动画
动画分为两种, 帧动画(frame animation) 和 补间动画(tween
animation).
研究: App Resources(看文档)
帧动画
1. 在 res/drawable 中创建一个xml文件, girl.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="100"/>
<item
android:drawable="@drawable/girl_2"
android:duration="100"/>
<item
android:drawable="@drawable/girl_3"
android:duration="100"/>
<item
android:drawable="@drawable/girl_4"
android:duration="100"/>
...
</animation-list>
用到图片都要放在drawable中.
2. 在布局文件中使用一个iv, 用于动画的显示
3. 在代码中调用
{{{class="brush:java"
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView iv = (ImageView)
findViewById(R.id.iv);
// 设置iv的动画背景
iv.setBackgroundResource(R.drawable.girl);
// 获取到动画背景资源
rocketAnimation = (AnimationDrawable)
iv.getBackground();
}
// 在4.0以上的模拟器上, 动画背景资源 (AnimationDrawable)一旦被得到, 就会自动播放动画
,
// 但是在2.3上, 需要一定的等待时间, 去调用 AnimationDrawable
的start方法
@Override
public boolean onTouchEvent(MotionEvent event)
{
// 播放动画
rocketAnimation.start();
return super.onTouchEvent(event);
}
}}}
补间动画
利用数学算法实现的动画效果. 有四种: 透明度, 旋转, 平移, 缩放, 以及这四者的组合.
透明度:
{{{class="brush:java"
// 声明透明度变化的动画
AlphaAnimation aa = new AlphaAnimation(0.0f,
1.0f);
aa.setDuration(2000); // 持续时间
aa.setRepeatCount(1); // 重复次数
// 重复方式, RESTART: 从新开始, REVERSE:
反转
aa.setRepeatMode(Animation.REVERSE);
iv.startAnimation(aa);
}}}
旋转:
{{{class="brush:java"
// 用参数最多的构造方法, 第一个参数从哪个角度,
第二个到哪个角度
// 第三个相对的x轴, 第四个相对于x轴原点的位置, 第五六为
y...
// 下面这个动画表示的就是, 相对于自己的中心旋转360度,
为什么?
// 第3参数表示以相对的x轴即view的上边线, 第4参数0.5f即横坐标为一半,
同理5,6参数
RotateAnimation ra = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF,
0.5f);
ra.setDuration(2000);
ra.setRepeatCount(2);
ra.setRepeatMode(Animation.REVERSE);
iv.startAnimation(ra);
}}}
平移:
{{{class="brush:java"
// fromXType, fromXValue, toXType, toXValue,
后面四个是Y, 值可以为负数, 表示反方向.
TranslateAnimation ta = new
TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0,
Animation.RELATIVE_TO_PARENT, 0f,
Animation.RELATIVE_TO_PARENT, 0,
Animation.RELATIVE_TO_PARENT, 0.5f);
ta.setDuration(2000);
ta.setRepeatCount(0);
ta.setRepeatMode(Animation.REVERSE);
iv.startAnimation(ta);
}}}
缩放:
{{{class="brush:java"
// fromX, toX, fromY, toY,
pivotXType, 这四个决定了x,y轴的缩放量
// pivotXValue,
pivotYType, pivotYValue, 这四个决定了缩放中心点
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(2);
sa.setRepeatMode(Animation.REVERSE);
// 设置动画完成之后是否显示最终的样子.
sa.setFillAfter(true);
iv.startAnimation(sa);
}}}
组合:
{{{class="brush:java"
//创建一个动画的集合, 参数表示是否共享 Interpolator. 关于Interpolator,
后面会介绍
AnimationSet set = new
AnimationSet(false);
// 设置动画插入器, 表示输入x, 得到的 y, 即函数
set.setInterpolator(new Interpolator() {
@Override
public float getInterpolation(float input)
{
return 0;
}
});
AlphaAnimation aa = new AlphaAnimation(0.2f,
1.0f);
aa.setDuration(2000);
aa.setRepeatCount(1);
aa.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(2);
ra.setRepeatMode(Animation.REVERSE);
TranslateAnimation ta = new
TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0,
Animation.RELATIVE_TO_PARENT,
-0.5f, Animation.RELATIVE_TO_PARENT,
0,
Animation.RELATIVE_TO_PARENT,
-0.5f);
ta.setDuration(2000);
ta.setRepeatCount(2);
ta.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(2);
sa.setRepeatMode(Animation.REVERSE);
sa.setFillAfter(true);
//把动画加到集合里
set.addAnimation(sa);
set.addAnimation(ta);
set.addAnimation(ra);
set.addAnimation(aa);
iv.startAnimation(set);
}}}
注意: view设置动画, 当动画完成后, 无论最后动画效果怎样, iv还是停留在原来的位置,
只是图像变了位置.
== 使用资源创建动画 ==
在 res目录下创建一个 anim 文件夹, 在里面创建一个动画xml文件, 有5中根节点可供选择,
对应5种补间动画.
透明度:
{{{class="brush:xml"
<?xml version="1.0" encoding="utf-8"?>
<alpha
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0.2"
android:toAlpha="1.0"
android:duration="2000"
>
</alpha>
}}}
对应的代码为:
{{{class="brush:java"
// 声明透明度变化的动画
Animation aa = AnimationUtils.loadAnimation(this,
R.anim.alpha);
iv.startAnimation(aa);
}}}
其他几种补间动画也都有相应的xml文件根节点
缩放:
<?xml version="1.0" encoding="utf-8"?>
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="0.2"
android:toXScale="1.0"
android:fromYScale="0.2"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"
>
</scale>
Animation sa = AnimationUtils.loadAnimation(this,
R.anim.scale);
iv.startAnimation(sa);
动画集, 动画的集合, 注意动画集是在同一时间执行所有动画,
而不是先执行一个再执行另一个.
另外, AnimationSet是Animation的子类. 动画集的拥有的属性,其中的动画的也会有,
并且动画集会覆盖其中的动画的属性
(旋转和平移):
<?xml version="1.0" encoding="utf-8"?>
android:fillAfter="true">
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" >
</rotate>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="50%p"
android:toYDelta="0" >
</translate>
</set>
50%p的意思是指父窗体的50%,
如果不写p表示自己的50%
//创建一个动画的集合.
Animation set =AnimationUtils.loadAnimation(this,
R.anim.set);
iv.startAnimation(set);
----------以下内容来自网上--------------
Frame
Animation
Frame
Animation是顺序播放事先做好的图像,跟电影类似。不同于animation package, Android
SDK提供了另外一个类AnimationDrawable来定义、使用Frame Animation。
Frame
Animation可以在XML
Resource定义(还是存放到res\anim文件夹下),也可以使用AnimationDrawable中的API定义。由于Tween
Animation与Frame
Animation有着很大的不同,因此XML定义的格式也完全不一样,其格式是:首先是animation-list根节点,animation-list根节点中包含多个item子节点,每个item节点定义一帧动画,当前帧的drawable资源和当前帧持续的时间。下面对节点的元素加以说明:
XML属性 | 说明 |
drawable | 当前帧引用的drawable资源 |
duration | 当前帧显示的时间(毫秒为单位) |
oneshot | 如果为true,表示动画只播放一次停止在最后一帧上,如果设置为false表示动画循环播放。 |
variablePadding | If
true, allows the drawable’s padding to change based on the current state that is
selected. |
visible | 规定drawable的初始可见性,默认为flase; |
下面就给个具体的XML例子,来定义一帧一帧的动画:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
<item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
<item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>
上面的XML就定义了一个Frame
Animation,其包含3帧动画,3帧动画中分别应用了drawable中的3张图片:rocket_thrust1,rocket_thrust2,rocket_thrust3,每帧动画持续200毫秒。
然后我们将以上XML保存在res/anim/文件夹下,命名为rocket_thrust.xml,显示动画的代码:
AnimationDrawable rocketAnimation;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView rocketImage =(ImageView)
findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.anim.rocket_thrust);
rocketAnimation =(AnimationDrawable) rocketImage.getBackground();
}
public boolean onTouchEvent(MotionEvent event){
if(event.getAction() == MotionEvent.ACTION_DOWN){
rocketAnimation.start();
return true;
}
return super.onTouchEvent(event);
}
代码运行的结果:3张图片按照顺序的播放一次.
有一点需要强调的是:启动Frame
Animation动画的代码rocketAnimation.start();不能在OnCreate()中,因为在OnCreate()中AnimationDrawable还没有完全的与ImageView绑定,在OnCreate()中启动动画,就只能看到第一张图片。这里实在拖曳事件中实现的。
下面,阅读Android
SDK中对AnimationDrawable的介绍,有个简单的了解:
AnimationDrawable |
获取、设置动画的属性 | |
int
getDuration() | 获取动画的时长 |
int
getNumberOfFrames() | 获取动画的帧数 |
boolean
isOneShot()
Void
setOneShot(boolean oneshot) | 获取oneshot属性 设置oneshot属性 |
void
inflate(Resurce r,XmlPullParser p, AttributeSet
attrs) | |
增加、获取帧动画 |
Drawable
getFrame(int index) | 获取某帧的Drawable资源 |
void
addFrame(Drawable frame,int duration) | 为当前动画增加帧(资源,持续时长) |
动画控制 |
void
start() | 开始动画 |
void
run() | 外界不能直接掉调用,使用start()替代 |
boolean
isRunning() | 当前动画是否在运行 |
void
stop() | 停止当前动画 |
Tween
Animation
一个tween动画将对视图对象中的内容进行一系列简单的转换(位置,大小,旋转,透明性)。如果你有一个文本视图对象,你可以移动它,旋转它,让它变大或让它变小,如果文字下面还有背景图像,背景图像也会随着文件进行转换。
使用XML来定义Tween
Animation
动画的XML文件在工程中res/anim目录,这个文件必须包含一个根元素,可以使<alpha><scale>
<translate>
<rotate>插值元素或者是把上面的元素都放入<set>元素组中,默认情况下,所以的动画指令都是同时发生的,为了让他们按序列发生,需要设置一个特殊的属性startOffset。动画的指令定义了你想要发生什么样的转换,当他们发生了,应该执行多长时间,转换可以是连续的也可以使同时的。例如,你让文本内容从左边移动到右边,然后旋转180度,或者在移动的过程中同时旋转,没个转换需要设置一些特殊的参数(开始和结束的大小尺寸的大小变化,开始和结束的旋转角度等等,也可以设置些基本的参数(例如,开始时间与周期),如果让几个转换同时发生,可以给它们设置相同的开始时间,如果按序列的话,计算开始时间加上其周期。
Tween
Animation共同的节点属性
属性[类型] | 功能 | 备注 |
Duration[long] | 属性为动画持续时间 | 时间以毫秒为单位 |
fillAfter
[boolean] | 当设置为true ,该动画转化在动画结束后被应用 |
fillBefore[boolean] | 当设置为true ,该动画转化在动画开始前被应用 |
interpolator | 指定一个动画的插入器 | 有一些常见的插入器 accelerate_decelerate_interpolator 加速-减速
动画插入器 accelerate_interpolator 加速-动画插入器 decelerate_interpolator 减速-
动画插入器 其他的属于特定的动画效果 |
repeatCount[int] | 动画的重复次数 | |
RepeatMode[int] | 定义重复的行为 | 1:重新开始
2:plays backward |
startOffset[long] | 动画之间的时间间隔,从上次动画停多少时间开始执行下个动画 |
zAdjustment[int] | 定义动画的Z
Order的改变 | 0:保持Z
Order不变 1:保持在最上层 -1:保持在最下层 |
表二 |
XML节点 | 功能说明 |
alpha | 渐变透明度动画效果 |
<alpha android:fromAlpha=”0.1″ android:toAlpha=”1.0″ android:duration=”3000″
/> |
fromAlpha | 属性为动画起始时透明度 | 0.0表示完全透明 1.0表示完全不透明 以上值取0.0-1.0之间的float数据类型的数字 duration为动画持续时间,ms单位 |
toAlpha
| 属性为动画结束时透明度 |
表三 |
scale | 渐变尺寸伸缩动画效果 |
<scale android:interpolator=
“@android:anim/accelerate_decelerate_interpolator” android:fromXScale=”0.0″ android:toXScale=”1.4″ android:fromYScale=”0.0″ android:toYScale=”1.4″ android:pivotX=”50%” android:pivotY=”50%” android:fillAfter=”false” android:startOffset=“700” android:duration=”700″ android:repeatCount=”10″
/> |
fromXScale[float]
fromYScale[float] | 为动画起始时,X、Y坐标上的伸缩尺寸 | 0.0表示收缩到没有 1.0表示正常无伸缩 值小于1.0表示收缩 值大于1.0表示放大 |
toXScale
[float] toYScale[float] | 为动画结束时,X、Y坐标上的伸缩尺寸 |
pivotX[float] pivotY[float] | 为动画相对于物件的X、Y坐标的开始位置 | 属性值说明:从0%-100%中取值,50%为物件的X或Y方向坐标上的中点位置 |
| | | |
表四 |
translate | 画面转换位置移动动画效果 |
<translate android:fromXDelta=”30″ android:toXDelta=”-80″ android:fromYDelta=”30″ android:toYDelta=”300″ android:duration=”2000″
/> |
fromXDelta toXDelta | 为动画、结束起始时 X坐标上的位置 | |
fromYDelta toYDelta | 为动画、结束起始时 Y坐标上的位置 | |
| | | |
表五 |
rotate | 画面转移旋转动画效果 |
<rotate android:interpolator=”@android:anim/accelerate_decelerate_interpolator” android:fromDegrees=”0″ android:toDegrees=”+350″ android:pivotX=”50%” android:pivotY=”50%” android:duration=”3000″
/> |
fromDegrees | 为动画起始时物件的角度 | 说明 当角度为负数——表示逆时针旋转 当角度为正数——表示顺时针旋转 (负数from——to正数:顺时针旋转) (负数from——to负数:逆时针旋转) (正数from——to正数:顺时针旋转) (正数from——to负数:逆时针旋转) |
toDegrees | 属性为动画结束时物件旋转的角度
可以大于360度 |
pivotX pivotY | 为动画相对于物件的X、Y坐标的开始位 | 说明:以上两个属性值 从0%-100%中取值 50%为物件的X或Y方向坐标上的中点位置
|