Android动画机制-传统动画

NanEaton 8年前
   <h2><strong>Android动画机制-传统动画</strong></h2>    <h2><strong>概述</strong></h2>    <p>Android动画机制-传统动画是指在Android3.0之前存在的两种动画机制,一种是逐帧动画,也就是号首先人工画出来每一个时间点的视图效果,然后一张图片一张图片的播放形成动画效果;</p>    <p>另一种就是补间动画,就是开发人员指定开始与结束的情况,然后系统自动生成中间的图形,不断播放,形成动画效果。</p>    <h2><strong>逐帧动画</strong></h2>    <p>要开发逐帧动画首先要画出每一个时间点的图形效果,也就是每一个帧,而且Android自身的解耦机制推荐我们应该在res中的anim(所有动画公共的文件夹)新建xml来设计动画。但还是在Java中使用代码也可以</p>    <h3><strong>简单使用</strong></h3>    <p>和其他动画不同的是,代表逐帧动画的根节点animation-list应该放在drawable文件夹中(Eclipse可以放在anim文件夹中)</p>    <p>在drwable中新建zhu_zhen.xml:</p>    <pre>  <code class="language-java"><animation-list xmlns:android="http://schemas.android.com/apk/res/android">      <item android:drawable="@drawable/fat_po_f01" android:duration="60"/>      <item android:drawable="@drawable/fat_po_f02" android:duration="60"/>      <item android:drawable="@drawable/fat_po_f03" android:duration="60"/>  </animation-list></code></pre>    <p>在layout中使用,既然是在drawable文件夹中,那么在@引用的时候就应该使用drawable,这里是把动画设置为ImageView的背景:</p>    <pre>  <code class="language-java"><ImageView          android:id="@+id/iv"          android:layout_width="100dp" android:layout_height="100dp"          android:background="@drawable/zhu_zhen"          android:scaleType="center"/>  <!--并且两个按钮分别控制开关-->      <LinearLayout android:layout_width="match_parent" android:layout_height="40dp"                    android:orientation="horizontal">          <Button android:layout_width="0dp" android:layout_height="match_parent"                  android:layout_weight="1"                  android:onClick="start" android:text="start"/>          <Button android:layout_width="0dp" android:layout_height="match_parent"                  android:layout_weight="1"                  android:onClick="stop" android:text="stop"/>      </LinearLayout></code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/9ac8a51dd33e827062a6b9ea4a66acb0.gif"></p>    <p style="text-align:center">android动画机制201611091025</p>    <p>在Activity中使用:</p>    <pre>  <code class="language-java">private AnimationDrawable mDrawable;        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);          init();      }        private void init() {          ImageView imageView = (ImageView) findViewById(R.id.iv);          //把Drawable强制转换成AnimationDrawable          mDrawable = (AnimationDrawable) imageView.getBackground();      }        public void start(View view) {          mDrawable.start();      }        public void stop(View view) {          mDrawable.stop();      }</code></pre>    <p>最后效果就是上面的阿宝如上面所示,注意AnimationDrawable也是Drawable的子类:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/e805c9f2965e974d91fad94344a7a910.png"></p>    <p style="text-align:center">sp161109_095811</p>    <h3><strong>注意事项</strong></h3>    <p>是每一帧的图片格式一定要是png而且不要直接改后缀名应该用另存为</p>    <p>加入每一帧是其他格式比如gif那么就会报错:Cannot generate texture from bitmap,而且ImageView整个是黑色的,无法正常显示。</p>    <h2><strong>补间动画</strong></h2>    <p>有四种形式,分别是AlpahAnimation、ScaleAnimation、TranslateAnimation、RotateAnimation,分别代表透明度动画、缩放动画,位移动画、旋转动画。注意这里每一个都是以Animation结尾。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/50534f4c1b92e306fe7cce3a291c9e62.png"></p>    <p style="text-align:center">sp161109_103711</p>    <p>四种常见的动画都是继承自Animation,还有一个是AnimationSet代表的是动画集合,另外一个不常用。</p>    <p>在上面的逐帧动画中也可以使用Java代码控制(有点麻烦)但是在补间动画中两种方式都比较简单。</p>    <p>四种动画共有的属性:</p>    <ol>     <li>duration持续时间</li>     <li>fillAfter在动画执行完是否保持最后一帧还是返回第一帧</li>    </ol>    <h3><strong>AlphaAnimation</strong></h3>    <p><strong>在xml中使用</strong></p>    <p>对应xml的标签是alpha</p>    <p>快速建立动画的方法: <strong>在AS中不要在anim总创建</strong> ,意思就是说不要点击anim文件夹右键,而是点击res右键,这样可以直接控制跟标签,而且AS会自动把文件转到相应的目录:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/0d360173bef65699ceff1fd32342bae4.png"></p>    <p style="text-align:center">sp161109_104522</p>    <p>透明度动画的特有属性:开始和结束的透明度</p>    <pre>  <code class="language-java"><alpha xmlns:android="http://schemas.android.com/apk/res/android"         android:fromAlpha="1.0"         android:toAlpha="0">  </alpha></code></pre>    <p>在Activity中使用:</p>    <pre>  <code class="language-java">private void init() {          mImageView = (ImageView) findViewById(R.id.iv);          mAlphaAnimation = (AlphaAnimation) AnimationUtils.loadAnimation(MainActivity.this, R.anim.tween_alpha);      }        public void start(View view) {          mAlphaAnimation.setDuration(3000);          mAlphaAnimation.setFillAfter(true);          mImageView.startAnimation(mAlphaAnimation);      }</code></pre>    <p>注意这里加载动画使用的是AnimationUtils.loadAnimation</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/6662c057c2e4a568438934b8424527de.gif"></p>    <p style="text-align:center">android动画机制tweenalpah2016</p>    <p><strong>用Java代码实现</strong></p>    <p>只要改写一句话即可:</p>    <pre>  <code class="language-java">//        mAlphaAnimation = (AlphaAnimation) AnimationUtils.loadAnimation(MainActivity.this, R.anim.tween_alpha);          mAlphaAnimation = new AlphaAnimation(1, 0);</code></pre>    <p>两个参数分别是开始和结束的透明度</p>    <h3><strong>ScaleAnimation</strong></h3>    <p>缩放动画也是两种实现方式一种是在xml,一个是在Java中,在xml对应的标签是scale。</p>    <p>特有属性:</p>    <ol>     <li> <p>fromYScale和toYScale(Y可以换成X)开始和结束的比例</p> </li>     <li> <p>pivotX和pivotY缩放的中心点</p> </li>    </ol>    <p>注意:一定要同时制定fromX和Y(两组四个属性)否则开始动画就会立即消失</p>    <p>没有指定缩放中心默认是以左上点作为中心</p>    <p><strong>在xml中实现</strong></p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <scale xmlns:android="http://schemas.android.com/apk/res/android"         android:fromXScale="1.0" android:pivotX="50%"         android:pivotY="50%" android:toXScale="0.2"         android:fromYScale="1.0" android:toYScale="0.2">  </scale></code></pre>    <p>Activity中的实现代码,基本没有变化:</p>    <pre>  <code class="language-java">private void init() {          mImageView = (ImageView) findViewById(R.id.iv);          mScaleAnimation = (ScaleAnimation) AnimationUtils.loadAnimation(MainActivity.this, R.anim.tween_scale);      }        public void start(View view) {          mScaleAnimation.setDuration(3000);          mScaleAnimation.setFillAfter(true);          mImageView.startAnimation(mScaleAnimation);      }</code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/d42484892f2a9a07f8060a14369d9cb9.gif"></p>    <p>android动画机制tweenscaleh2016</p>    <p><strong>使用Java实现</strong></p>    <pre>  <code class="language-java">//      mScaleAnimation = (ScaleAnimation) AnimationUtils.loadAnimation(MainActivity.this, R.anim.tween_scale);          mScaleAnimation = new ScaleAnimation(1, 0.2f, 1, 0.2f);</code></pre>    <p>但是这里指定缩放中心困难,指定缩放比例简单</p>    <h3><strong>TranslateAnimation</strong></h3>    <p>表示位置移动的动画,特有属性:fromXDelta(当然还有to,而且XY可以互换)</p>    <p><strong>在xml中实现</strong></p>    <pre>  <code class="language-java"><translate xmlns:android="http://schemas.android.com/apk/res/android"              android:fromXDelta="0" android:toXDelta="100">  </translate></code></pre>    <p>在Activity中引用,和上面的代码基本一样:</p>    <pre>  <code class="language-java">private void init() {          mImageView = (ImageView) findViewById(R.id.iv);          mTranslateAnimation = (TranslateAnimation) AnimationUtils.loadAnimation(MainActivity.this, R.anim.tween_translate);      }        public void start(View view) {          mTranslateAnimation.setDuration(3000);          mTranslateAnimation.setFillAfter(true);          mImageView.startAnimation(mTranslateAnimation);      }</code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/2431ffe2ea656a4686801a8c7baaae21.gif"></p>    <p style="text-align:center">android动画机制tweentranslate2016</p>    <p><strong>使用Java实现</strong></p>    <p>依旧就是更改一句话,不过少创建一个文件:</p>    <pre>  <code class="language-java">//        mTranslateAnimation = (TranslateAnimation) AnimationUtils.loadAnimation(MainActivity.this, R.anim.tween_translate);          mTranslateAnimation = new TranslateAnimation(0, 100, 0, 0);</code></pre>    <p>效果和上面一样</p>    <h3><strong>RotateAnimation</strong></h3>    <p>表示旋转的动画,特有属性:</p>    <ol>     <li>fromDegrees和toDegrees开始和结束的角度</li>     <li>pivotX和pivotY旋转的中心点</li>    </ol>    <p><strong>在xml中实现</strong></p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <rotate xmlns:android="http://schemas.android.com/apk/res/android"          android:fromDegrees="0"          android:pivotX="50%" android:pivotY="50%" android:toDegrees="3600">  </rotate></code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/083095d5a1411161493dbc762e7212b1.gif"></p>    <p>android动画机制tweenrotate</p>    <p>在Avtivity中引用:</p>    <pre>  <code class="language-java">private void init() {          mImageView = (ImageView) findViewById(R.id.iv);          mRotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(MainActivity.this,R.anim.tween_roate);      }        public void start(View view) {          mRotateAnimation.setDuration(3000);          mRotateAnimation.setFillAfter(true);          mImageView.startAnimation(mRotateAnimation);      }</code></pre>    <p><strong>使用Java实现</strong></p>    <p>老规矩,只因为在人群改写一句代码,从此忘不了你的容颜啊!!!</p>    <pre>  <code class="language-java">//        mRotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(MainActivity.this,R.anim.tween_roate);      mRotateAnimation = new RotateAnimation(0,3600);</code></pre>    <p>这里还是中心点不好指定,默认是以左上角位旋转中心</p>    <h3><strong>AnimationSet</strong></h3>    <p>最后一个,写完去吃饭</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ec8024db40a5ddab67fc88eda686392f.gif"></p>    <p style="text-align:center">img</p>    <p>代表动画集合的类,就可可以同时播放几个效果,在xml对应的标签是set,注意的子标签(scale,translate,rotate,alpha)有duration和fillAfter属性,他们单独使用没有这个属性。</p>    <p>而且还可以指定差速器(下一节细说)</p>    <p><strong>在xml中实现</strong></p>    <pre>  <code class="language-java"><set xmlns:android="http://schemas.android.com/apk/res/android"       android:duration="3000"       android:fillAfter="true">      <alpha          android:fromAlpha="1.0"          android:toAlpha="0">      </alpha>      <rotate          android:fromDegrees="0"          android:pivotX="50%" android:pivotY="50%" android:toDegrees="3600">      </rotate>        <scale          android:fromXScale="1.0" android:fromYScale="1.0"          android:pivotX="50%" android:pivotY="50%"          android:toXScale="0.2" android:toYScale="0.2">      </scale>        <translate          android:fromXDelta="0" android:toXDelta="100">      </translate>  </set></code></pre>    <p>就是把刚才的四个动画复制一下,不过这里在跟标签中指定了时间和fillAfter属性</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/b02c6ff233a3196071893c269059c88c.gif"></p>    <p style="text-align:center">android动画机制tweenset1141</p>    <p>在Activity中引用,效果还有一点炫:</p>    <pre>  <code class="language-java">private void init() {          mImageView = (ImageView) findViewById(R.id.iv);          mAnimationSet = (AnimationSet) AnimationUtils.loadAnimation(MainActivity.this, R.anim.tween_set);      }        public void start(View view) {          mImageView.startAnimation(mAnimationSet);      }</code></pre>    <p><strong>在java代码实现</strong></p>    <pre>  <code class="language-java">private void init() {          mImageView = (ImageView) findViewById(R.id.iv);  //      构造参数是否分享差速器          mAnimationSet = new AnimationSet(true);            mRotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(MainActivity.this,R.anim.tween_roate);          mRotateAnimation.setDuration(3000);          mRotateAnimation.setFillAfter(true);            mScaleAnimation = (ScaleAnimation) AnimationUtils.loadAnimation(MainActivity.this,R.anim.tween_scale);          mScaleAnimation.setDuration(3000);          mScaleAnimation.setFillAfter(true);            mTranslateAnimation = new TranslateAnimation(0, 100, 0, 0);            mAlphaAnimation = new AlphaAnimation(1, 0);          mAlphaAnimation.setDuration(3000);          mAlphaAnimation.setFillAfter(true);            mAnimationSet.addAnimation(mRotateAnimation);          mAnimationSet.addAnimation(mTranslateAnimation);          mAnimationSet.addAnimation(mScaleAnimation);          mAnimationSet.addAnimation(mAlphaAnimation);      }        public void start(View view) {          mImageView.startAnimation(mAnimationSet);      }</code></pre>    <p>比较麻烦</p>    <h3><strong>Animation好玩的属性</strong></h3>    <ol>     <li>setRepeatCount和setRepeatMode设置重复次数和模式</li>     <li>setStartOffset设置开始延迟</li>    </ol>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/b2c69b03c003</p>    <p> </p>