zoukankan      html  css  js  c++  java
  • 【Android】两种动画介绍(Tween动画、Frame动画)

            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;
    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同样也可以在代码中设置。


    [java] view plaincopy
    1. imageView.setBackgroundResource(R.anim.animation);  




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


    [java] view plaincopy
    1. /**拿到ImageView对象**/  
    2. imageView = (ImageView)findViewById(R.id.imageView);  
    3. /**通过ImageView对象拿到背景显示的AnimationDrawable**/  
    4. 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  否则会看不到透明的效果 。这里切记切记~~


    谢谢CSDN博主宣雨松,牛人一枚。以后还会多多向他学习。




  • 相关阅读:
    49. 字母异位词分组
    73. 矩阵置零
    Razor语法问题(foreach里面嵌套if)
    多线程问题
    Get json formatted string from web by sending HttpWebRequest and then deserialize it to get needed data
    How to execute tons of tasks parallelly with TPL method?
    How to sort the dictionary by the value field
    How to customize the console applicaton
    What is the difference for delete/truncate/drop
    How to call C/C++ sytle function from C# solution?
  • 原文地址:https://www.cnblogs.com/secbook/p/2655019.html
Copyright © 2011-2022 走看看