Android动画框架之视图动画基本使用

      之前在学习View 滑动的时候其实就是View动画的一种展现形式了,当时介绍了有7中方法可以实现View的滑动,截止目前还有Sroller,动画以及ViewDragHelper实现没有介绍,今天的内容里面就包含了部分View的滑动实现,这里说部分主要有两个原因:

  • 今天介绍的视图动画实现的滑动是不可交互的滑动实现
  • 后面可以通过3.0之后的属性动画完整实现

1,基础知识

好的,那几天就来简单看一下Android动画框架中的视图动画的基本使用。首先,先来看一个效果图,里面包含了视图动画可以实现的独立动画效果

从上面的效果图可以看出,视图动画API主要可以帮助我们实现View的以下几个电话效果:

  • 透明度变化
  • 旋转(围绕一个坐标点)
  • 伸缩(围绕一个坐标点)
  • 平移

对应的API分别为:

  • AlphaAnimation
    AlphaAnimation alphaAnimation1=new AlphaAnimation(1,0);
    alphaAnimation1.setDuration(timeLength);
  • RotateAnimation
    RotateAnimation rotateAnimation1=new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    rotateAnimation1.setDuration(timeLength);
  • ScaleAnimation
    ScaleAnimation scaleAnimation=new ScaleAnimation(0,1,0,1, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    scaleAnimation.setDuration(timeLength);
  • TranslateAnimation
    TranslateAnimation translateAnimation=new TranslateAnimation(startX,endX,startY,endY);
    translateAnimation.setDuration(timeLength);

这些API都是Animation的子类,文档如下:

android.view.animation
类 Animation

java.lang.Object
  android.view.animation.Animation

所有已实现的接口:

Cloneable

直接已知子类:

AlphaAnimation, AnimationSet, RotateAnimation, ScaleAnimation, TranslateAnimation

由文档可以看出,它还有一个子类是AnimationSet,顾名思义就是动画集合的意思,也就是说添加一组动画到View,然后这些动画效果同时展示在View上,这样就会有一个组合动画的效果。比如:

AnimationSet set=new AnimationSet(true);
......
set.addAnimation(alphaAnimation1);
set.addAnimation(alphaAnimation2);
set.addAnimation(rotateAnimation1);
set.addAnimation(scaleAnimation);
set.addAnimation(translateAnimation);
testImage.startAnimation(set);

此外,针对每一个动画对象,我们都可以为其添加动画状态监听,这样就可以在动画开始和结束的时候做一些逻辑操作,比如:

scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation) {

    }

    @Override
    public void onAnimationEnd(Animation animation) {
        Toast.makeText(MainActivity.this,"平移动画开始",Toast.LENGTH_SHORT).show();
        testImage.startAnimation(translateAnimation);
    }

    @Override
    public void onAnimationRepeat(Animation animation) {

    }
});

针对每一个动画对象,我们都可以在动画的三种状态的时候做逻辑操作:

  • start
  • end
  • repeat

2 案例实现

实现步骤:

第一步:构建布局,一个按钮,两个ImageView并且重叠,下面一张ImageView主要用于记录上面一张ImageView的初始位置,方便后面验证视图动画完成的知识View显示的变化,交互时间还是停留在初始位置

第二步:获取动画对象,设置状态监听,实现动画间平滑衔接,并吐司信息

第三步:根据展示效果给ImageView添加动画

代码:

activity_main.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.hfut.operationanimation.MainActivity">

    <Button
        android:id="@+id/controll_button"
        android:layout_marginTop="30dp"
        android:textSize="30dp"
        android:text="动画测试"
        android:onClick="animationTest"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ImageView
        android:layout_marginTop="30dp"
        android:id="@+id/test_image_background"
        app:layout_constraintTop_toBottomOf="@+id/controll_button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:src="@color/colorAccent"
        android:layout_width="180dp"
        android:layout_height="240dp" />
    <ImageView
        android:layout_marginTop="30dp"
        android:id="@+id/test_image"
        app:layout_constraintTop_toBottomOf="@+id/controll_button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:src="@drawable/testimage"
        android:layout_width="180dp"
        android:layout_height="240dp" />

</android.support.constraint.ConstraintLayout>

MainActivity代码:

package com.hfut.operationanimation;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.Toast;

/**
 * @author why
 * @date 2018-9-7 21:22:18
 */
public class MainActivity extends AppCompatActivity {

    ImageView testImage;
    int startX;
    int startY;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        testImage=findViewById(R.id.test_image);
        //监听当前Image的点击事件
        testImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this,"Image被点击了",Toast.LENGTH_SHORT).show();
            }
        });

        startX=(int)testImage.getX();
        startY=(int)testImage.getY();
    }


    public void animationTest(View view){

        //动画集合对象
        final AnimationSet set=new AnimationSet(true);

        //透明度动画
        AlphaAnimation alphaAnimation1=new AlphaAnimation(1,0);
        alphaAnimation1.setDuration(1000);
        final AlphaAnimation alphaAnimation2=new AlphaAnimation(0,1);
        alphaAnimation2.setDuration(1000);
        //旋转动画
        final RotateAnimation rotateAnimation1=new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        rotateAnimation1.setDuration(2000);
        //缩放动画
        final ScaleAnimation scaleAnimation=new ScaleAnimation(0,1,0,1, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        scaleAnimation.setDuration(2000);
        //平移动画
        final TranslateAnimation translateAnimation=new TranslateAnimation(startX,200,startY,300);
        translateAnimation.setDuration(2000);
        //设置平移后是否留在当前位置
        translateAnimation.setFillAfter(true);

        translateAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                Toast.makeText(MainActivity.this,"平移动画结束",Toast.LENGTH_SHORT).show();
//                try {
//                    Thread.sleep(1000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                testImage.startAnimation(set);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });

        scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                Toast.makeText(MainActivity.this,"平移动画开始",Toast.LENGTH_SHORT).show();
                testImage.startAnimation(translateAnimation);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });


        rotateAnimation1.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                Toast.makeText(MainActivity.this,"缩放动画开始",Toast.LENGTH_SHORT).show();
                testImage.startAnimation(scaleAnimation);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });

        alphaAnimation2.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
              Toast.makeText(MainActivity.this,"旋转动画开始",Toast.LENGTH_SHORT).show();
              testImage.startAnimation(rotateAnimation1);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        //View开启动画
        testImage.startAnimation(alphaAnimation1);
        alphaAnimation1.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                Toast.makeText(MainActivity.this,"透明度动画开始",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onAnimationEnd(Animation animation) {
              testImage.startAnimation(alphaAnimation2);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });

//        set.addAnimation(alphaAnimation1);
//        set.addAnimation(alphaAnimation2);
//        set.addAnimation(rotateAnimation1);
//        set.addAnimation(scaleAnimation);
//        set.addAnimation(translateAnimation);
//        testImage.startAnimation(set);
    }
}

这里说几点注意事项

  • 上面的示例旋转和伸缩使用的坐标是相对参数,我们也可以使用绝对坐标加上View自身宽高实现,可参见Android中实现滑动(上)----基础知识,这样就可以理解如何获取当前View的绝对坐标,下面就是计算View中心点绝对坐标的简易表达式:

rotateX=x+view.width/2;

rotateY=y+view.height/2;

  • 平移动画完成后,如果不设置其停留在平移后的当前位置,则默认会返回初始位置
  • 在验证ImageView交互位置未移动的现象,需要给ImageView设置一下点击之后的逻辑

​​​​​​​​​​​​​​到这里,Android中关于视图动画的基本使用就简单介绍到这里了,使用其实还是蛮简单的。

猜你喜欢

转载自blog.csdn.net/hfut_why/article/details/82503761