Android的三种动画

Android动画详解

帧动画

  所谓帧动画其实很好理解,就是通过在一定的时间间隔内,将一组图片顺序播放出来,从而打到动画的效果,我们通过简单的帧动画例子来说明一下。
  下面是帧动画的xml资源代码,animation-list就是帧动画的标签,它包含的item就是每一帧的图像。

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item
        android:drawable="@mipmap/one"
        android:duration="500"/>
    <item
        android:drawable="@mipmap/two"
        android:duration="500"/>
    <item
        android:drawable="@mipmap/three"
        android:duration="500"/>
    <item
        android:drawable="@mipmap/four"
        android:duration="500"/>
    <item
        android:drawable="@mipmap/five"
        android:duration="50"/>
    <item
        android:drawable="@mipmap/six"
        android:duration="50"/>
</animation-list>

  接下来我们创建帧动画例子activity的布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:text="开始"
        android:id="@+id/start"
        android:layout_marginTop="20dp"
        android:onClick="onStart"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:id="@+id/stop"
        android:text="停止"
        android:onClick="onStop"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop ="20dp"
        android:id="@+id/imageView"/>

</LinearLayout>

  然后是activity里面的代码

public class FrameAnimationActivity extends AppCompatActivity {
    private AnimationDrawable animationDrawable; //此处写错了 写成了Animation
    private ImageView imageView;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.frame_activity);
        init();
    }
    private void init(){
        imageView = (ImageView)findViewById(R.id.imageView);

        imageView.setBackgroundResource(R.drawable.frame_anim);

        animationDrawable = (AnimationDrawable) imageView.getBackground();
    }

    public void onStart(View view){
        if(animationDrawable != null && !animationDrawable.isRunning()){
            animationDrawable.start();
        }
    }

    public void onStop(View view){
        if(animationDrawable != null && animationDrawable.isRunning()){
            animationDrawable.stop();
        }
    }
}

  通过上面的代码可以知道,帧动画主要需要记住3点,1是动画资源文件-drawable里面的文件,animation-list以及它的子标签item。2是AnimationDrawable这个类以及这个类的实例对象通过imageView控件的getBackground方法得到的。3是AnimationDrawable的用法(start()、stop()这个几个方法)。

补间动画

  补间动画主要有四种操作:透明变化、缩放控制、旋转控制、移动控制。这四种动画变化都是通过资源文件来实现的,我们在res文件夹里面创建anim文件夹。然后根据需要创建相应的xml文件,这里通过一个例子说明用法。
  下面是alpha、scale、rotate、translate、set对应的xml文件,set文件是将上面所有动画种类选择性地集合在一起,同时执行。

  • alpha.xml
<?xml version="1.0" encoding="utf-8" ?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:fromAlpha="0"
    android:toAlpha="1"
    android:duration="4000"/>
    
<!-- interpolator:表示采用这个算法,设置动画播放的平缓的程度 -->
<!-- fromAlpha:初始透明度-->
<!-- toAlpha:最终透明度-->
  • scale.xml
<?xml version="1.0" encoding="utf-8" ?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:fromYScale="0"
    android:fromXScale="0"
    android:toXScale="1"
    android:toYScale="1"
    android:pivotY="0"
    android:pivotX="100%"
    android:duration="3000"/>

<!-- 缩放的的基点 pivotX和pivotY  如果在百分号数值后面加一个p,就是控件左上角加上父控件百分之多少的值-->
<!-- fromYScale:初始Y轴的缩放比例-->
<!-- fromXScale:初始X轴的缩放比例-->
<!-- toYScale:最终Y轴的缩放比例-->
<!-- toXScale:最终X轴的缩放比例-->

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

    <!-- 旋转的的基点 pivotX和pivotY  如果在百分号数值后面加一个p,就是控件左上角加上父控件百分之多少的值-->
  • translate.xml
<?xml version="1.0" encoding="utf-8" ?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toYDelta="500"
    android:toXDelta="500"
    android:duration="3000"/>
  • set.xml
<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:shareInterpolator="true">


    <scale
        android:pivotY="50%"
        android:pivotX="50%"
        android:fromXScale="0"
        android:fromYScale="0"
        android:toYScale="1"
        android:toXScale="1"
        android:duration="1000"/>

<!-- 会覆盖前面的scale动画-->

    <scale
        android:pivotY="50%"
        android:pivotX="50%"
        android:fromXScale="1"
        android:fromYScale="1"
        android:toYScale="0"
        android:toXScale="0"
        android:duration="1000"/>

    <alpha
        android:fromAlpha="0"
        android:toAlpha="1"
        android:duration="1000"/>
</set>

  补间动画的布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:text="透明动画"
        android:onClick="onAlpha"
        android:layout_marginTop="20dp"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:onClick="onScale"
        android:text="缩放动画"/>

    <Button
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:layout_marginTop="20dp"
        android:onClick="onRotate"
        android:text="旋转动画"/>

    <Button
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:layout_marginTop="20dp"
        android:onClick="onTranslate"
        android:text="位移动画"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:onClick="onSet"
        android:text="动画组合"/>

    <ImageView
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_gravity="center_horizontal"
        android:id="@+id/imageView"
        android:background="@mipmap/five"/>

</LinearLayout>

  activity代码

public class TweenAnimationActivity extends AppCompatActivity {

    private Animation animation;
    private ImageView imageView;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tween_activity);

        init();
    }

    private void init(){
        imageView = (ImageView)findViewById(R.id.imageView);
    }
    public void onAlpha(View view){
        animation = AnimationUtils.loadAnimation(this, R.anim.alpha);
        imageView.startAnimation(animation);
    }
    public void onScale(View view){
        animation = AnimationUtils.loadAnimation(this, R.anim.scale);
        imageView.startAnimation(animation);

    }
    public void onRotate(View view){
        animation = AnimationUtils.loadAnimation(this, R.anim.rotate);
        imageView.startAnimation(animation);
    }
    public void onTranslate(View view){
        animation = AnimationUtils.loadAnimation(this, R.anim.translate);
        imageView.startAnimation(animation);
    }

    /**
     *
     * @param view
     *
     * 对于set的理解就是,set.xml文件里面定义这四种动画,然后同时执行,也可以定义一样的动画类型,但是会覆盖前面的同类型动。
     */

    public void onSet(View view){
        animation = AnimationUtils.loadAnimation(this, R.anim.set);
        imageView.startAnimation(animation);
    }
}

  通过上面示例代码可以看出。补间动画主要记住3点,1是补间动画资源文件的写法,2是Animation类和AnimationUtils类loadAnimation()方法的用法, 3是插值器,参考这篇文章

属性动画

  属性动画需要和补间动画区分开来,因为前者的变化是真实的,后者的变化是不真实的,补间动画只是给人一种障眼法,比如当补间动画移动之后,你点击它的显示区域,发现不会响应点击事件,只有点击它的原始区域才会响应点击事件。而属性动画就不一样了,只要移动在屏幕可显示区域就可以响应点击事件。同样地给出一个例子来说明。

  • 布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:onClick="onAlpha"
        android:text="透明"/>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:onClick="onScale"
        android:text="缩放"/>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:onClick="onRotate"
        android:text="旋转"/>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:onClick="onTranslate"
        android:text="移动"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onSet"
        android:text="集合"/>

    <Button
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_marginTop="30dp"
        android:layout_gravity="center_horizontal"
        android:text="我是移动的控件"
        android:id="@+id/move_button"/>

</LinearLayout>
  • activity代码
public class AttributeAnimationActivity extends AppCompatActivity {
    private ObjectAnimator objectAnimator;
    private Button show_button;
    private final static String TAG = "提示";

    private AnimatorSet animatorSet = new AnimatorSet();
    ObjectAnimator rotateObjectAnimator1 = new ObjectAnimator();
    ObjectAnimator translateObjectAnimator1 = new ObjectAnimator();
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.attribute_activity);
        init();

        animatorSet.addListener(new AnimatorListenerAdapter() {

            private AnimatorSet animatorSet2 = new AnimatorSet();

            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
//                animation.cancel();
                Log.d(TAG, "onAnimationEnd: 动画完成,开始回来动画");
                ObjectAnimator rotateObjectAnimator2 = new ObjectAnimator();
                ObjectAnimator translateObjectAnimator2 = new ObjectAnimator();

                rotateObjectAnimator2 = rotateObjectAnimator2.ofFloat(show_button, "rotation", 0f, 360f);
                translateObjectAnimator2 = translateObjectAnimator2.ofFloat(show_button, "translationY", 200f, 150f, 100f, 50f, 0f);

                animatorSet2.setDuration(2000);

                animatorSet2.play(rotateObjectAnimator2).with(translateObjectAnimator2);
                animatorSet2.start();
            }

        });
    }
    private void init(){
        show_button = (Button)findViewById(R.id.move_button);
    }

    public void onAlpha(View view){
        Log.d(TAG, "onAlpha: ");
        //value是不定长形参数组。里面的值代表动画的变化过程值。
        objectAnimator = objectAnimator.ofFloat(show_button, "alpha", 1f, 0.5f, 0f, 0.5f, 1f);
        objectAnimator.setDuration(2000);
        objectAnimator.start();
    }

    public void onScale(View view){
        Log.d(TAG, "onScale: ");
        objectAnimator = objectAnimator.ofFloat(show_button, "scaleY", 0f, 1f, 2f, 1f);
        objectAnimator.setDuration(2000);
        objectAnimator.start();
    }

    public void onRotate(View view){
        Log.d(TAG, "onRotate: ");
        objectAnimator = objectAnimator.ofFloat(show_button, "rotation", 0f, 90f, 360f);
        objectAnimator.setDuration(2000);
        objectAnimator.setRepeatCount(3);
        objectAnimator.setRepeatMode(ValueAnimator.RESTART);
        objectAnimator.start();
    }
    public void onTranslate(View view){
        Log.d(TAG, "onTranslate: ");
        objectAnimator = objectAnimator.ofFloat(show_button, "translationY", 0f, 50f, 100f, 150f, 200f);
        objectAnimator.setDuration(2000);
        objectAnimator.start();
    }

    public void onSet(View view){
        Log.d(TAG, "onSet: ");
        rotateObjectAnimator1 = rotateObjectAnimator1.ofFloat(show_button, "rotation", 0f, 90f,  360f);
        translateObjectAnimator1 = translateObjectAnimator1.ofFloat(show_button, "translationY", 0f, 50f, 100f, 150f, 200f);


        animatorSet.setDuration(2000);
        animatorSet.play(rotateObjectAnimator1).with(translateObjectAnimator1);
        animatorSet.start();
    }
}

  属性动画需要记住3点,1是属性动画不依赖xml文件。2是ObjectAnimator类以及它的ofFloat()方法的用法。3是AnimatorSet类的用法。

总结

  Android动画类型从简单到复杂是,帧动画-补间动画-属性动画。同时灵活程度也是如此,帧动画可以实现一些简单的显示效果,如果想要移动、旋转等操作就需要用到补间动画了,而如果要实现是跟为复杂或者可响应点击事件的功能,那就只能选择属性动画了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值