android之逐帧,补间动画详解。

在android的世界中有三种动画,它们就是逐帧动画,补间动画,属性 动画。接下来我就分别演示下三种动画的简单用法。

各动画的定义:

  1. 逐帧动画:就是短时间切换图片,让人们肉眼看起来是连续的,其实就是播放一组图片。就相当于gif图片的生成、还有我们小时候看电影的时候。那时是通过切换胶片来达到放电影。我是农村的,小时候经常看到。不知道你们有木有经历过。。。
  2. 补间动画:就是操作某个控件让其展现出旋转、渐变、移动、缩放的这么一种转换过程,我们称为补间动画。我们也可以XML形式定义动画,也可以java代码实现。
  3. 属性动画:这个是Android3.0才出现的。它弥补了以前补间动画的一些缺陷。它是通过改变对象的属性来进行的。

逐帧动画的使用

在res/drawable下建立个anni.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/huan"
        android:duration="200" />
    <item
        android:drawable="@drawable/yin"
        android:duration="200" />
    <item
        android:drawable="@drawable/ni"
        android:duration="200" />
    <item
        android:drawable="@drawable/lai"
        android:duration="200" />
    <item
        android:drawable="@drawable/dao"
        android:duration="200" />
    <item
        android:drawable="@drawable/wo"
        android:duration="200" />
    <item
        android:drawable="@drawable/de"
        android:duration="200" />
    <item
        android:drawable="@drawable/bo"
        android:duration="200" />
    <item
        android:drawable="@drawable/ke"
        android:duration="200" />

</animation-list>

android:oneshot false代表的是无限循环,true代表的是只循环一次。不写的话默认是false

main_activity.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.edu.animsimple.MainActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onclick"
        android:text="逐帧动画"
        />

    <ImageView
        android:id="@+id/img"
        android:src="@drawable/anni"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
</LinearLayout>

我们就已经为这张图片引用动画了,运行结果为:

这里写图片描述

我们也可以不在xml中写android:src=”@drawable/anni” 可以在代码中写。

MainActivity代码如下:

import android.graphics.drawable.AnimationDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private ImageView mImg;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mImg= (ImageView) findViewById(R.id.img);

    }

    /**
     * 逐帧动画
     * @param view
     */
    public void onclick(View view) {
        mImg.setImageResource(R.drawable.zhuzhen);//为该图片设置动画
        AnimationDrawable animationDrawable= (AnimationDrawable) mImg.getDrawable();//获取drawable对象
        animationDrawable.start();//开启动画
         //animationDrawable.stop();//停止动画
    }

}

点击按钮后,运行结果:
这里写图片描述

好了,逐帧动画就是这么点内容。

补间动画

我们先看下补间动画的用法:
- AlphaAnimation:透明度(alpha)渐变效果,对应alpha标签。
- TranslateAnimation:位移渐变,需要指定移动点的开始和结束坐标,对应translate标签。
- ScaleAnimation:缩放渐变,可以指定缩放的参考点,对应scale标签。
- RotateAnimation:旋转渐变,可以指定旋转的参考点,对应rotate标签。
- AnimationSet:组合渐变,支持组合多种渐变效果,对应set标签。

既可以在xml中写,也可以在java代码中写,下面就两种情况都演示下吧

在res/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:duration="2000"
    android:fillAfter="true"
    >
</alpha>

android:fromAlpha=”1.0”表示的是完全不透明。
android:toAlpha=”0.0”表示的是完全透明。
android:duration=”2000”表示的是时长。
android:fillAfter=”true”表示的是动画结束时停在那。

在res/anim目录下建立个translate .xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="100%"
    android:fromYDelta="100%"
    android:toXDelta="0%"
    android:toYDelta="0%"
    android:duration="2000"
    android:fillAfter="true"
 android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    >
</translate>

android:fromXDelta=”100%”表示的x点是从相对于自己左边缘x坐标一倍地方开始。
android:fromYDelta=”100%”表示的是y点是相对于自己左边缘y坐标一倍地方开始
android:toXDelta=”0%”表示x点的是相对于自己左边缘x轴结束
android:toYDelta=”0%”表示的是y点从哪相对于自己左边缘y轴结束
android:duration=”2000”表示的是动画时长
android:fillAfter=”true”表示的是动画结束时,停在那,
android:interpolator=”@android:anim/accelerate_decelerate_interpolator表示的是动画过程中是先加速后减速。

android:fromXDelta这样的属性值有三种写法,就以这种属性情况解释下,其他都一样;

  1. android:fromXDelta=“200” 就是确定的值,表示的是就是从这x坐标开始
  2. android:fromXDelta=“200%”表示的是相对于自身控件而言的
  3. android:fromXDelta=“200%p”这个表示的是相对于父容器而言的。

第一种情况很好理解,就是从给定的位置开始动画

第二种情况,也比较好理解。给个例子吧。一个按钮,点击按钮发生动画。如下图:
这里写图片描述

第三情况也不太难理解。还是给张图比较好理解:

这里写图片描述

在res/anim目录下建立个scale .xml代码如下:

```
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXScale="1"
    android:toXScale="2"
    android:fromYScale="1"
    android:toYScale="2"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="3000"
    >
</scale>

android:pivotX=”50%”
android:pivotY=”50%”
这个表示的是相对于自身而言,50%,50%表示的就是以自身的中心点缩放。
如果是具体的值,比如50,50,就是相对于自身控件的左边缘50,上边缘50进行缩放。
如果是50%p,50%p那就是相对于父控件进行缩放。。其他的都比较好理解,就不说了。 比如 android:fromXScale=”1” ,android:toXScale=”2”表示的是x放大两倍。

在res/anim目录下建立个 rotate.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="3000"
    >
</rotate>

android:fromDegrees=”0” 表示的是从0度开始
android:toDegrees=”360” 表示的是旋转360度结束
android:pivotX=”50%” 相对于自身而言
android:pivotY=”50%” 相对于自身而言
android:duration=”3000” 动画时间

android:pivotX="50%"  
android:pivotY="50%" 
 这跟上面缩放的意思是一样的。也有三种情况。具体值,相对于自己,相对于父容器。了。

在res/anim目录下建立个 set.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:shareInterpolator="true"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:repeatMode="reverse"
    >

    <!--透明度动画-->
    <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0.0"
        android:duration="2000"
        android:fillAfter="true"
        />
    <!--位移动画-->
    <translate
        android:fromXDelta="100%"
        android:fromYDelta="100%"
        android:toXDelta="0%"
        android:toYDelta="0%"
        android:duration="2000"
       />

    <!--旋转动画-->
    <rotate
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="3000"
        />
    <!--缩放动画-->
    <scale
        android:fromXScale="1"
        android:toXScale="2"
        android:fromYScale="1"
        android:toYScale="2"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="3000"
        />
</set>

组合动画就是把这些动画组合在一起,其实也没什么。上面的没出现过的几个属性说下吧。
android:shareInterpolator=”true” true表示的是都是共享一个插值器。
android:repeatMode=”reverse” reverse表示的是循环重复。

接下来就运行下:

activity_main.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.edu.animsimple.MainActivity">

    <Button
        android:id="@+id/alpha"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="透明度动画"
        />

    <Button
        android:id="@+id/translate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="位移动画"
        />

    <Button
        android:id="@+id/scale"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="縮放动画"
        />

    <Button
        android:id="@+id/rotate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="旋转动画"
        />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/set"
        android:text="组合动画"
        />
</LinearLayout>

MainActivity.java代码如下:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private Button alphaBtn ,translateBtn,scaleBtn,rotateBtn,setBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        alphaBtn= (Button) findViewById(R.id.alpha);
        translateBtn= (Button) findViewById(R.id.translate);
        scaleBtn= (Button) findViewById(R.id.scale);
        rotateBtn= (Button) findViewById(R.id.rotate);
        setBtn= (Button) findViewById(R.id.set);
        alphaBtn.setOnClickListener(this);
        translateBtn.setOnClickListener(this);
        scaleBtn.setOnClickListener(this);
        rotateBtn.setOnClickListener(this);
        setBtn.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.alpha:
                Animation alpha= AnimationUtils.loadAnimation(this,R.anim.alpha);
                alphaBtn.startAnimation(alpha);
                break;
            case R.id.translate:
                Animation translate= AnimationUtils.loadAnimation(this,R.anim.translate);
                translateBtn.startAnimation(translate);
                break;
            case R.id.scale:
                Animation scale= AnimationUtils.loadAnimation(this,R.anim.scale);
                scaleBtn.startAnimation(scale);
                break;
            case R.id.rotate:
                Animation rotate= AnimationUtils.loadAnimation(this,R.anim.rotate);
                rotateBtn.startAnimation(rotate);
                break;
            case R.id.set:
                Animation set= AnimationUtils.loadAnimation(this,R.anim.set);
                setBtn.startAnimation(set);
                break;
        }
    }
}

运行结果:

这里写图片描述

通过xml的方式实现学习完了,接下来怎么通过java代码实现:

MainActivity.java代码如下:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button alphaBtn, translateBtn, scaleBtn, rotateBtn, setBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        alphaBtn = (Button) findViewById(R.id.alpha);
        translateBtn = (Button) findViewById(R.id.translate);
        scaleBtn = (Button) findViewById(R.id.scale);
        rotateBtn = (Button) findViewById(R.id.rotate);
        setBtn = (Button) findViewById(R.id.set);
        alphaBtn.setOnClickListener(this);
        translateBtn.setOnClickListener(this);
        scaleBtn.setOnClickListener(this);
        rotateBtn.setOnClickListener(this);
        setBtn.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.alpha:
                /**
                 * 这是通过xml实现的
                 */
//                Animation alpha= AnimationUtils.loadAnimation(this,R.anim.alpha);
//                alphaBtn.startAnimation(alpha);
                /**
                 * 这是通过java代码实现的,跟xml实现的效果一样
                 */
                AlphaAnimation alpha = new AlphaAnimation(1.0f, 0.0f);
                alpha.setDuration(2000);
                alpha.setFillAfter(true);
                alphaBtn.startAnimation(alpha);
                break;
            case R.id.translate:
                /**
                 * 这是通过xml实现的
                 */
//                Animation translate= AnimationUtils.loadAnimation(this,R.anim.translate);
//                translateBtn.startAnimation(translate);
                /**
                 * 通过java代码实现,跟xml实现的效果一样
                 */
                TranslateAnimation translate = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
                        1.0f, Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF,
                        1.0f, Animation.RELATIVE_TO_SELF, 0.0f
                );
                translate.setDuration(2000);
                translate.setInterpolator(new AccelerateDecelerateInterpolator());
                translateBtn.startAnimation(translate);
                break;
            case R.id.scale:
                /**
                 * 这是通过xml实现的
                 */
//                Animation scale= AnimationUtils.loadAnimation(this,R.anim.scale);
//                scaleBtn.startAnimation(scale);
                /**
                 * 通过java代码实现,跟xml实现的效果一样
                 */
                ScaleAnimation scale = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f,
                        Animation.RELATIVE_TO_SELF, 0.5f,
                        Animation.RELATIVE_TO_SELF, 0.5f
                );
                scale.setDuration(3000);
                scaleBtn.startAnimation(scale);
                break;
            case R.id.rotate:
                /**
                 * 这是通过xml实现的
                 */
//                Animation rotate= AnimationUtils.loadAnimation(this,R.anim.rotate);
//                rotateBtn.startAnimation(rotate);
                /**
                 * 通过java代码实现,跟xml实现的效果一样
                 */
                RotateAnimation rotate = new RotateAnimation(0.0f, 360.0f
                        , Animation.RELATIVE_TO_SELF, 0.5f,
                        Animation.RELATIVE_TO_SELF, 0.5f
                );
                rotate.setDuration(3000);
                rotateBtn.startAnimation(rotate);
                break;
            case R.id.set:
                /**
                 * 这是通过xml实现的
                 */
//                Animation set = AnimationUtils.loadAnimation(this, R.anim.set);
//                setBtn.startAnimation(set);
                /**
                 * 通过java代码实现,只实现了两种动画的组合。
                 */
                RotateAnimation rotateSet = new RotateAnimation(0.0f, 360.0f
                        , Animation.RELATIVE_TO_SELF, 0.5f,
                        Animation.RELATIVE_TO_SELF, 0.5f
                );
                TranslateAnimation translateSet = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
                        1.0f, Animation.RELATIVE_TO_SELF, 0.0f,
                        Animation.RELATIVE_TO_SELF,
                        1.0f, Animation.RELATIVE_TO_SELF, 0.0f
                );
                AnimationSet  set=new AnimationSet(true);
                set.setDuration(5000);
                set.setInterpolator(new LinearInterpolator());
                set.addAnimation(rotateSet);
                set.addAnimation(translateSet);
                set.setRepeatMode(Animation.REVERSE);//启动模式
                setBtn.startAnimation(set);
                break;
        }
    }
}

运行效果是一样的。就不给出来额。xml跟java代码实现效果是一样的。这个就看个人爱好了,我是比较喜欢通过java代码实现。

到这里已经把逐帧动画跟补间动画学完了。还有属性动画就留在明天写了,这篇有点长了。

总结:

我也是名初学者,写博客主要是回顾下自己学的东西,你认为不对的地方请大胆指正。谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值