一、Android 中的动画
(1)在android中动画的实现方式有两种类型:
1.view Animation (应用在view中的一种动画)
1)tween animation (在res/anim目录中创建:四种+set)
例子1:四种动画及集合
public class MainActivity extends Activity { private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView=(ImageView)findViewById(R.id.imageView1); } /**实现view对象的淡入淡出*/ public void doAlpha(View v){ imageView.startAnimation(AnimationUtils.loadAnimation(this,R.anim.alpha01)); } /**实现view对象的缩放功能*/ public void doScale(View v){ imageView.startAnimation(AnimationUtils.loadAnimation(this,R.anim.scale01)); } /**实现view对象的平移*/ public void doTranslate(View v){ imageView.startAnimation(AnimationUtils.loadAnimation(this,R.anim.trans01)); } /**实现view对象的旋转*/ public void doRotate(View v){ imageView.startAnimation(AnimationUtils.loadAnimation(this,R.anim.rotate01)); } /**窗口焦点发生变化时执行此方法*/ @Override public void onWindowFocusChanged(boolean hasFocus) { imageView.startAnimation(AnimationUtils.loadAnimation(this,R.anim.set01)); } public void onClick(View v){ ActivityOptions ao=ActivityOptions.makeCustomAnimation(this,R.anim.scale01,R.anim.rotate01); startActivity(new Intent(this,OtherActivity.class),ao.toBundle());//Bundle b=new Bundle() } } |
<alpha xmlns:android="http://schemas.android.com/apk/res/android" android:fromAlpha="0" android:toAlpha="1" android:duration="2000" /> <!-- fromAlpha :起始透明度 toAlpha:结束透明度 1.0表示完全不透明 0.0表示完全透明 --> |
<rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="0" android:toDegrees="720" android:duration="3000" android:pivotX="50%" android:pivotY="50%" android:repeatCount="2" android:interpolator="@android:anim/accelerate_decelerate_interpolator" /> fromDegrees:表示旋转的起始角度 toDegrees:表示旋转的结束角度 repeatCount:旋转的次数 默认值是0 代表旋转1次 如果值是repeatCount=4 旋转5次,值为-1或者infinite时,表示补间动画永不停止 repeatMode 设置重复的模式。默认是restart。当repeatCount的值大于0或者为infinite时才有效。 repeatCount=-1 或者infinite 循环了 还可以设成reverse,表示偶数次显示动画时会做与动画文件定义的方向相反的方向动行。 --> |
<scale xmlns:android="http://schemas.android.com/apk/res/android" android:fromXScale="0" android:fromYScale="0" android:toXScale="1" android:toYScale="1" android:pivotX="50%" android:pivotY="50%" android:duration="3000"> </scale> <!-- fromXScale:表示沿着x轴缩放的起始比例 toXScale:表示沿着x轴缩放的结束比例 fromYScale:表示沿着y轴缩放的起始比例 toYScale:表示沿着y轴缩放的结束比例
图片中心点: android:pivotX="50%" android:pivotY="50%"
--> |
<translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="0" android:toXDelta="-100%" android:fromYDelta="0" android:toYDelta="100%" android:duration="3000" android:fillAfter="true" /> <!-- android:interpolator 动画的渲染器 1、accelerate_interpolator(动画加速器) 使动画在开始的时候 最慢,然后逐渐加速 2、decelerate_interpolator(动画减速器)使动画在开始的时候 最快,然后逐渐减速 3、accelerate_decelerate_interpolator(动画加速减速器) 中间位置分层: 使动画在开始的时候 最慢,然后逐渐加速 使动画在开始的时候 最快,然后逐渐减速 结束的位置最慢 fromXDelta 动画起始位置的横坐标 toXDelta 动画起结束位置的横坐标 fromYDelta 动画起始位置的纵坐标 toYDelta 动画结束位置的纵坐标 duration 动画的持续时间 --> |
<set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0" android:toXDelta="100%" android:fromYDelta="0" android:toYDelta="0" android:duration="3000" android:fillAfter="true"/> <rotate android:fromDegrees="0" android:toDegrees="720" android:duration="3000" android:startOffset="3000" android:pivotX="50%" android:pivotY="50%" android:interpolator="@android:anim/accelerate_decelerate_interpolator"/> </set> |
例子2:frame animation (res/drawable目录下创建的一个animation-list元素)
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> false是无限循环,true是只有一次 <item android:drawable="@drawable/png_01" android:duration="3000" /> <item android:drawable="@drawable/png_02" android:duration="3000" /> <item android:drawable="@drawable/png_03" android:duration="3000" /> </animation-list> |
public class MainActivity extends Activity { ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv=(ImageView) findViewById(R.id.imageView1); } /**window窗口获得焦点以后启动一个帧动画*/ @Override public void onWindowFocusChanged(boolean hasFocus) { //设定背景 //iv.setBackgroundResource(R.drawable.frame01); //获得背景Drawable对象 AnimationDrawable d=(AnimationDrawable)iv.getBackground(); //Log.i("TAG", "iv.getBackground()"); //启动动画 d.start(); } }
|
(2)Property Animation (3.0,应用在任意对象上)
1)资源对象: ValueAnimator,ObjectAnimator,AnimatorSet
a)ValueAnimator 对象不能直接作用于对象属性上,可以监听动画值的变化
b)ObjectAnimator 可以直接作用于对象属性上
例子3:ValueAnimator 和ObjectAnimator
public class MainActivity extends Activity {
private ImageView img; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); img=(ImageView) findViewById(R.id.imgId); } public void onClick(View v){ Toast.makeText(this, "hello", 1).show(); } public void onProperty01(View v){ ObjectAnimator oa=(ObjectAnimator)AnimatorInflater.loadAnimator(this,R.animator.obj01); Log.i("TAG", "oa="+oa); //应用在对象属性上的动画必须有对应的set方法 oa.setTarget(img); //启动 oa.start(); }
public void onProperty02(View v){ //ValueAnimator不能直接作用于某个对象的属性 ValueAnimator a=(ValueAnimator)AnimatorInflater.loadAnimator(this,R.animator.obj02); Log.i("TAG", "a="+a); a.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Float f=(Float)animation.getAnimatedValue(); //改变对象布局 img.layout(img.getWidth(),img.getHeight(),img.getWidth()+f.intValue(),img.getHeight()+f.intValue()); img.lyout(int l, int t, int r, int b)左、上、右、下 } }); //将动画应用在img对象上 a.start(); } } |
obj01: <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:propertyName="translationX" android:valueFrom="0" android:valueTo="100" android:duration="3000" android:repeatCount="2" android:repeatMode="reverse" android:valueType="floatType"/> |
obj02: <animator xmlns:android="http://schemas.android.com/apk/res/android" android:valueFrom="0" android:valueTo="200" android:duration="3000" android:valueType="floatType" > </animator> |
c)AnimatorSet 实现多个属性动画的顺序或一起操作
例子4:动画集合
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> "together"是一起执行动画 <objectAnimator android:propertyName="rotationX" android:valueFrom="0" android:valueTo="360" android:valueType="floatType"/> <objectAnimator android:propertyName="translationX" android:valueFrom="0" android:valueTo="100" android:valueType="floatType"/> </set> |
//按顺序执行动画 set.playSequentially(o2,o1); //一起执行动画 set.playTogether(items) |
2)资源文件:res/animator/xxx.xml
资源文件的加载要借助AnimatorInflater对象的loadAnimator方法
public class MainActivity extends Activity {
private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView=(ImageView) findViewById(R.id.imageView1); } public void onClick01(View v){ //基于res/animator中的xml获得AnimatorSet对象 AnimatorSet set=(AnimatorSet)AnimatorInflater.loadAnimator(this,R.animator.set01); //设置持续时间 set.setDuration(3000); set.setTarget(imageView); set.start(); } public void onClick02(View v){ //获得一个对象动画 ObjectAnimator o1=ObjectAnimator.ofFloat(v,"rotationX",0,360); o1.setDuration(3000); //获得一个对象动画 ObjectAnimator o2=ObjectAnimator.ofFloat(imageView,"translationX",0,200); o2.setDuration(3000); //构建一个动画集合 AnimatorSet set=new AnimatorSet(); //按顺序执行动画 set.playSequentially(o2,o1); //set.playTogether(items) //set.setTarget(imageView); //启动动画 set.start(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } |