Android动画开发(三)——补间动画

补间动画就是指开发者指定动画的开始、动画的结束的"关键帧",而动画变化的"中间帧"由系统计算,并补齐。
补间动画有四种:

  • 淡入淡出: alpha
  • 位移:translate
  • 缩放:scale
  • 旋转: rotate

补间动画的实现方式有两种,类似于帧动画,

1、 XML 形式补间动画

补间动画一般也是通过 xml 来实现,对于 xml 形式补间动画的定义,也是需要在 res/anim/ 文件夹下定义动画资源,如:
alpha_anim.xml

(1)定义动画资源:res\anim\tween_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="100"
        android:fromYDelta="0"
        android:toYDelta="100" />
</set>

(2)定义xml布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:padding="15dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/imv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:src="@mipmap/kaws4"/>
    <Button
        android:id="@+id/play2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="播放动画"
        android:textSize="25sp"
        android:textColor="#FFFFFF"
        android:background="#000000"/>
</LinearLayout>

(3)Animation 控制图片播放动画

package com.example.androidtest;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;

public class Animator3Activity extends AppCompatActivity {
    // tween_image;
    Button tween_start;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_animator3);
        final ImageView tween_image = findViewById(R.id.imv);
        tween_start = findViewById(R.id.play2);
        // 加载动画资源
        final Animation anim = AnimationUtils.loadAnimation(this,R.anim.anim);
        //设置动画结束后保留结束状态
        anim.setFillAfter(true);
        tween_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                tween_image.startAnimation(anim);
            }
        });
    }
}

效果如下:

 

2、Java 代码实现补间动画

  Translate  位移

 Animation translateAnimation = new TranslateAnimation(0,500,0,500);
        // 创建平移动画的对象:平移动画对应的Animation子类为TranslateAnimation
        // 参数分别是:
        // 1. fromXDelta :视图在水平方向x 移动的起始值
        // 2. toXDelta :视图在水平方向x 移动的结束值
        // 3. fromYDelta :视图在竖直方向y 移动的起始值
        // 4. toYDelta:视图在竖直方向y 移动的结束值
        translateAnimation.setDuration(3000);
        // 播放动画直接 startAnimation(translateAnimation)
        //如:
        mButton.startAnimation(translateAnimation);
  • Scale:  缩放
        Animation scaleAnimation= new ScaleAnimation(0,2,0,2,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        // 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方向同理)
        scaleAnimation.setDuration(3000);
        // 使用
        mButton.startAnimation(scaleAnimation);
  • Rotate:  旋转
   Animation rotateAnimation = new RotateAnimation(0,270,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        // 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方向同理)
        rotateAnimation.setDuration(3000);
        mButton.startAnimation(rotateAnimation);
  • Alpha  淡入淡出,渐变
 Animation alphaAnimation = new AlphaAnimation(1,0);
        // 1. fromAlpha:动画开始时视图的透明度(取值范围: -1 ~ 1)
        // 2. toAlpha:动画结束时视图的透明度(取值范围: -1 ~ 1)
        alphaAnimation.setDuration(3000);
        mButton.startAnimation(alphaAnimation);
  • 动画组合
        // 组合动画设置
        AnimationSet setAnimation = new AnimationSet(true);

        // 特别说明以下情况
        // 因为在下面的旋转动画设置了无限循环(RepeatCount = INFINITE)
        // 所以动画不会结束,而是无限循环
        // 所以组合动画的下面两行设置是无效的
        setAnimation.setRepeatMode(Animation.RESTART);
        setAnimation.setRepeatCount(1);// 设置了循环一次,但无效

        // 旋转动画
        Animation rotate = new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        rotate.setDuration(1000);
        rotate.setRepeatMode(Animation.RESTART);
        rotate.setRepeatCount(Animation.INFINITE);

        // 平移动画
        Animation translate = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT,-0.5f,
                TranslateAnimation.RELATIVE_TO_PARENT,0.5f,
                TranslateAnimation.RELATIVE_TO_SELF,0
                ,TranslateAnimation.RELATIVE_TO_SELF,0);
        translate.setDuration(10000);

        // 透明度动画
        Animation alpha = new AlphaAnimation(1,0);
        alpha.setDuration(3000);
        alpha.setStartOffset(7000);

        // 缩放动画
        Animation scale1 = new ScaleAnimation(1,0.5f,1,0.5f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        scale1.setDuration(1000);
        scale1.setStartOffset(4000);

        // 将创建的子动画添加到组合动画里
        setAnimation.addAnimation(alpha);
        setAnimation.addAnimation(rotate);
        setAnimation.addAnimation(translate);
        setAnimation.addAnimation(scale1);
        // 使用
        mButton.startAnimation(setAnimation);

动画监听

为了实现一些需求,如动画结束后开始另一个动画或者页面跳转,这时候就需要监听动画。

 Animation.addListener(new AnimatorListener() {
          @Override
          public void onAnimationStart(Animation animation) {
              //动画开始时执行
          }

           @Override
          public void onAnimationRepeat(Animation animation) {
              //动画重复时执行
          }

         @Override
          public void onAnimationCancel()(Animation animation) {
              //动画取消时执行
          }

          @Override
          public void onAnimationEnd(Animation animation) {
              //动画结束时执行
          }
      });
package com.example.androidtest;

import androidx.appcompat.app.AppCompatActivity;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import com.example.androidtest.R;

public class AnimatorActivity extends AppCompatActivity {

    private TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_animator);
        tv=findViewById(R.id.tv);

        //tv.animate().translationYBy(500).setDuration(2000).start();//沿Y轴在2s内平移500个单位
        //tv.animate().alpha(0).setDuration(2000).start();//2秒钟的渐变,从有到无
//        ValueAnimator valueAnimator=ValueAnimator.ofInt(0,100);
//        valueAnimator.setDuration(2000);
//        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
//            @Override
//            public void onAnimationUpdate(ValueAnimator valueAnimator) {
//                //valueAnimator实际的值
//                Log.d("aaaaa",valueAnimator.getAnimatedValue()+"");
//                //动画的进度0-1
//                Log.d("aaaaaaa",valueAnimator.getAnimatedFraction()+"");
//            }
//        });
//        valueAnimator.start();

        ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(tv,"translationY",0,500,200,800);
        //将tv从0移动到500再移动200
        objectAnimator.setDuration(5000);
        objectAnimator.start();
    }
}

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Demo.demo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值