• 【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博主宣雨松,牛人一枚。以后还会多多向他学习。




  • 相关阅读:
    程序优化
    obsidium 重定位
    Obsidium V1.3.0.4 脱壳
    SEH 栈溢出
    DWORD SHOOT
    两种堆表学习
    修改网页转向
    WireShark过滤语法
    获取系统信息学习
    怎么在 渗透无键盘 查询机
  • 原文地址:https://www.cnblogs.com/secbook/p/2655019.html
Copyright © 2020-2023  润新知