AndroidStudio-3.2.1(十八)组件动画和布局视图动画

时间:2024-03-21 08:59:49

Android 中的控件动画可以分为以下3类:逐帧动画、补间动画、属性动画。本篇介绍android中补间动画的使用。

补间动画需要指定动画的开始和结束的"关键帧",而动画变化的"中间帧"由系统计算,并通过插补器interpolator自动补齐。
补间动画有四种:

  • 透明度: alpha
  • 位移:translate
  • 缩放:scale
  • 旋转: rotate

系统提供的插补器,常用有以下几种:

  • accelerate_decelerate_interpolator 其变化开始和结束速率较慢,中间加速
  • accelerate_interpolator 其变化开始速率较慢,后面加速
  • decelerate_interpolator 其变化开始速率较快,后面减速
  • linear_interpolator 其变化速率恒定
  • anticipate_interpolator 其变化开始向后甩,然后向前

AndroidStudio-3.2.1(十八)组件动画和布局\视图动画

四种基本补间动画

动画的实现可以通过xml或java代码两种方式。我们先使用java代码:

透明度
                    // 1. fromAlpha:动画开始时视图的透明度(取值范围: -1 ~ 1)
                    // 2. toAlpha:动画结束时视图的透明度(取值范围: -1 ~ 1)
                    Animation alphaAnimation = new AlphaAnimation(1,0);
                    alphaAnimation.setDuration(2000);
                    imgRun.startAnimation(alphaAnimation);
位移
                    // 创建平移动画的对象:平移动画对应的Animation子类为TranslateAnimation
                    // 参数分别是:
                    // 1. fromXDelta :视图在水平方向x 移动的起始值
                    // 2. toXDelta :视图在水平方向x 移动的结束值
                    // 3. fromYDelta :视图在竖直方向y 移动的起始值
                    // 4. toYDelta:视图在竖直方向y 移动的结束值
                    Animation translateAnimation = new TranslateAnimation(0,500,0,500);
                    translateAnimation.setDuration(3000);
                    imgRun.startAnimation(translateAnimation);
缩放
                    // 1. fromX :动画在水平方向X的结束缩放倍数
                    // 2. toX :动画在水平方向X的结束缩放倍数
                    // 3. fromY :动画开始前在竖直方向Y的起始缩放倍数
                    // 4. toY:动画在竖直方向Y的结束缩放倍数
                    // 5. pivotXType:缩放轴点的x坐标的模式
                    // 6. pivotXValue:缩放轴点x坐标的相对值
                    // 7. pivotYType:缩放轴点的y坐标的模式
                    // 8. pivotYValue:缩放轴点y坐标的相对值
                    // pivotXType = Animation.ABSOLUTE:缩放轴点的x坐标 =  View左上角的原点 在x方向 加上 pivotXValue数值的点(y方向同理)
                    // pivotXType = Animation.RELATIVE_TO_SELF:缩放轴点的x坐标 = View左上角的原点 在x方向 加上 自身宽度乘上pivotXValue数值的值(y方向同理)
                    // pivotXType = Animation.RELATIVE_TO_PARENT:缩放轴点的x坐标 = View左上角的原点 在x方向 加上 父控件宽度乘上pivotXValue数值的值 (y方向同理)
                    Animation scaleAnimation= new ScaleAnimation(0,2,0,2,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
                    scaleAnimation.setDuration(2000);
                    imgRun.startAnimation(scaleAnimation);
旋转
                    // 1. fromDegrees :动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
                    // 2. toDegrees :动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
                    // 3. pivotXType:旋转轴点的x坐标的模式
                    // 4. pivotXValue:旋转轴点x坐标的相对值
                    // 5. pivotYType:旋转轴点的y坐标的模式
                    // 6. pivotYValue:旋转轴点y坐标的相对值
                    // pivotXType = Animation.ABSOLUTE:旋转轴点的x坐标 =  View左上角的原点 在x方向 加上 pivotXValue数值的点(y方向同理)
                    // pivotXType = Animation.RELATIVE_TO_SELF:旋转轴点的x坐标 = View左上角的原点 在x方向 加上 自身宽度乘上pivotXValue数值的值(y方向同理)
                    // pivotXType = Animation.RELATIVE_TO_PARENT:旋转轴点的x坐标 = View左上角的原点 在x方向 加上 父控件宽度乘上pivotXValue数值的值 (y方向同理)
                    Animation rotateAnimation = new RotateAnimation(0,270,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
                    rotateAnimation.setDuration(2000);
                    imgRun.startAnimation(rotateAnimation);

组合动画

可以把集中基本动画进行组合,我们使用xml方式。在/res/anim/文件夹下添加一个xml文件set_anim.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">
    <scale
        android:duration="3000"
        android:fromXScale="0.0"
        android:fromYScale="0.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.0"
        android:toYScale="1.0"/>
    <alpha
        android:duration="3000"
        android:fromAlpha="1.0"
        android:toAlpha="0.5" />
    <rotate
        android:fromDegrees="0"
        android:toDegrees="720"
        android:pivotX = "50%"
        android:pivotY="50%"
        android:duration = "3000"/>
    <translate
        android:fromXDelta="0"
        android:toXDelta="200"
        android:fromYDelta="0"
        android:toYDelta="0"
        android:duration = "3000"/>
</set>

代码调用:

   					Animation anim = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.set_anim);
                    //设置动画结束后保留结束状态
                    anim.setFillAfter(true);
                    imgRun.startAnimation(anim);

监听动画事件

可以监听动画的开始、结束、重复的事件。

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

                        }

                        @Override
                        public void onAnimationEnd(Animation animation) {
                            Toast.makeText(getApplicationContext(),"动画结束",Toast.LENGTH_SHORT).show();
                        }

                        @Override
                        public void onAnimationRepeat(Animation animation) {

                        }
                    });

自定义补间动画

Animation 是补间动画抽象基类,我们自定义动画就是要集成这个类,并覆写两个方法initialize和applyTransformation。
initialize:里面可获取控件的宽高和父容器的宽高
applyTransformation:这里面是实现动画的关键。在动画执行过程中,这个方法会被调用很多次,每次传进来的interpolatedTime值是不同的,这个值是根据你采用的插补器类型由系统计算好传过来,范围是0-1。Transformation参数代表了补间动画在不同时刻对图形或组件的变形程度。

public class JumpeggAnimation extends Animation {
    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        t.getMatrix().setTranslate((float) Math.sin(interpolatedTime*24)*50,(float) Math.sin(interpolatedTime*24)*25);
        super.applyTransformation(interpolatedTime, t);
    }
}

现在我们要实现一个JumpEgg的震动效果(上下左右摆动),就是要对控件的X、Y坐标进行周期性的变化,本文使用了数学中的正弦函数作为周期函数,使用interpolatedTime参数作为周期变化因子,实现了X\Y轴的左右变化。使用如下:

                    Animation jupAnimation= new JumpeggAnimation();
                    jupAnimation.setDuration(1500);
                    imgRun.startAnimation(jupAnimation);

AndroidStudio-3.2.1(十八)组件动画和布局\视图动画

布局与视图动画

android 对各种布局Layout也支持动画,用到LayoutAnimationController 类.比如我们对上面的几个按钮添加动画,也就是对他们的父容器LinearLayout设置动画:

        Animation alphaAnimation = new AlphaAnimation(1,0);
        alphaAnimation.setDuration(2000);
        LayoutAnimationController lac =new LayoutAnimationController(alphaAnimation,0.5f);//0.5f表示每个子项的动画在上一个子项动画运行到一半时再开始
        lac.setOrder(LayoutAnimationController.ORDER_RANDOM);//子项的展示顺序
        LinearLayout linearLayout = findViewById(R.id.linearLayout);
        linearLayout.setLayoutAnimation(lac);

LayoutAnimationController 不仅可以对布局设置动画,也可以对各种集合视图的子项展示、增删等添加动画,比如ListView、CardView等。