第七单元属性动画以及差值器以及svg动画

属性动画的意义

一、背景
有了补间动画,为什么还需要属性动画

补间动画限制:
1、补间动画只能定义两个关键帧在透明、旋转、位移和倾斜这四个属性的变换,但是属性动画可以定义任何属性的变化。
3、补间动画只能对 UI 组件(view)执行动画,但属性动画可以对任何对象执行动画。
4、补间动画没有改变view 的属性,只是加了视觉效果
5、补间动画效果单一

属性动画的优势:
1、任何对象都可以,不在限制于View
2、不止是四种基本变换

属性动画特点

https://www.jianshu.com/p/2412d00a0ce4

ValueAnimator

java代码方式实现
package com.fenghongzhang.anim;

import android.animation.ValueAnimator;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;

public class Main2Activity extends AppCompatActivity {

    private static final String TAG = "Main2Activity";
    private Button btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        initView();
    }

    public void btn(View view) {
        ValueAnimator valueAnimator = ValueAnimator.ofInt(btn.getLayoutParams().width, 500);
        //动画时间
        valueAnimator.setDuration(2000);
        //重复次数
        valueAnimator.setRepeatCount(3);
        //重复方向,
        valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                //改变的值
                Integer animatedValue = (Integer) animation.getAnimatedValue();
                Log.i(TAG, "onAnimationUpdate: "+animatedValue);

                btn.getLayoutParams().width = animatedValue;
                btn.requestLayout();
            }
        });

        valueAnimator.start();
    }

    private void initView() {
        btn = (Button) findViewById(R.id.btn);
    }
}

xml方式显现
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:repeatCount="1"
    android:repeatMode="reverse"

    android:propertyName="translationX"
    android:valueFrom="100"
    android:valueTo="400"

    android:interpolator="@android:anim/accelerate_interpolator"
    android:valueType="floatType" />

<!--android:valueFrom="0"   // 初始值
    android:valueTo="100"  // 结束值
    android:valueType="intType" // 变化值类型 :floatType & intType

//重要
 android:propertyName="rotation" alpha scaleX或者scaleY  translationX 变化的方式. 透明,旋转.移动

    android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
    android:startOffset ="1000" // 动画延迟开始时间(ms)
    android:fillBefore =true// 动画播放完后,视图是否会停留在动画开始的状态,默认为true
    android:fillAfter =false// 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
    android:fillEnabled=true// 是否应用fillBefore值,对fillAfter值无影响,默认为true
    android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
    android:repeatCount =0// 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
    android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
-->


java代码

   public void btn1(View view) {
        Animator animator = AnimatorInflater.loadAnimator(this, R.animator.bianhua);
        animator.setTarget(btn1);
        animator.start();
    }

使用 ObjectAnimator 实现四种动画

这里我打算通过使用 ObjectAnimator 实现四大动画框架:

alpha
scaleX/scaleY
translateX/translateY
rotation

java 代码

public void btn2(View view) {
//        final ObjectAnimator animator = ObjectAnimator.ofFloat(btn, "alpha", 0, 1);
//        ObjectAnimator animator = ObjectAnimator.ofFloat(btn, "translationX", 0, 200);
//        ObjectAnimator animator = ObjectAnimator.ofFloat(btn, "translationY", 0, 200, 100);
//        ObjectAnimator animator = ObjectAnimator.ofFloat(btn, "scaleX", 1, 5);
//        ObjectAnimator animator = ObjectAnimator.ofFloat(btn, "scaleY", 1, 5);
//        ObjectAnimator animator = ObjectAnimator.ofFloat(btn, "rotation", 0, 270);
        ObjectAnimator animator = ObjectAnimator.ofFloat(btn, "rotationY", 0, 180, -100);

        animator.setDuration(2000);
        animator.setRepeatCount(2);
        animator.setInterpolator(new AccelerateInterpolator());
//        animator.setInterpolator(new DecelerateInterpolator());
        animator.setRepeatMode(ValueAnimator.RESTART);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {

            }
        });
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                
            }

            @Override
            public void onAnimationEnd(Animator animation) {

            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        animator.start();
    }

AnimationSet 动画集合

AnimatorSet.play(Animator anim) :播放当前动画
AnimatorSet.after(long delay) :将现有动画延迟x毫秒后执行
AnimatorSet.with(Animator anim) :将现有动画和传入的动画同时执行
AnimatorSet.after(Animator anim) :将现有动画插入到传入的动画之后执行
AnimatorSet.before(Animator anim) : 将现有动画插入到传入的动画之前执行
AnimatorSet.playSequentially(Animator… items):参数中的动画列表依次执行
AnimatorSet.playTogether(Animator… items):参数中的动画同时执行

java 代码

  AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(3000);
        animatorSet.setInterpolator(new LinearInterpolator());

        ObjectAnimator translationX = ObjectAnimator.ofFloat(btn, "translationX", 0, 300);
        ObjectAnimator rotation = ObjectAnimator.ofFloat(btn, "rotation", 0, 720);
        ObjectAnimator scaleX = ObjectAnimator.ofFloat(btn, "scaleX", 1, 5);
        ObjectAnimator scaleY = ObjectAnimator.ofFloat(btn, "scaleY", 1, 5);
        ObjectAnimator alpha = ObjectAnimator.ofFloat(btn, "alpha", 1, 0);

        //顺序播放
        animatorSet.playSequentially(translationX, rotation, scaleX, scaleY, alpha);
//        animatorSet.playTogether(scaleX, scaleY);

//        animatorSet.play(translationX).before(rotation);
//        animatorSet.play(scaleX).with(scaleY).after(3000).before(alpha);

        animatorSet.start();

svg动画

介绍
https://www.jianshu.com/p/47b0ae970dd5

Google在Android5.X中增加了对SVG矢量图形的支持,这对于创造新的高效率动画具有很深远的意义。

1、svg
A.可伸缩矢量图形(Scalable Vector Graphics)
B.定义用于网络的基于矢量的图形
C.使用XML格式定义图形
D.图像在放大或改变尺寸的情况下其图形质量不会有所损失
E.万维网联盟的标准
F.与诸如DOM和XML之类的W3C标准是一个整体

2、path标签
A. M = moveto(x, y):将画笔移动到指定的坐标位置上,但是并没有发生绘制。
B. L = lineto(x, y):画一条直线到指定的坐标位置上。
C. H = horizontal lineto(x):画水平线在指定的x坐标位置。
D. V = vertical lineto(y):画一条垂直线在指定的y坐标位置。
E. C = curveto(x1, y1, x2, y2, endX, endY):三次贝赛曲线
F. S = smooth curveto(x2, y2, endX, endY):三次贝赛曲线
G. G = quadratic Belzier curveto(x, y, endX, endY):二次贝赛曲线
H. T = smooth quadratic Belizer curveto(endX, endY):映射前面路径后的终点
I. A = elliptical Arc(rx, ry, xRotation, flag1, flag2, x, y):弧线
J. Z = colsepath():关闭路径
注意:
A. 坐标轴是以(0,0)为中心的, x轴水平向右,y轴水平向下。
B. 所有指令大小写均可。大写表示绝对坐标,参照全局坐标系;小写表示相对坐标,参照父容器的坐标系。
C. 指令和数据间的空格可以省略。
D. 同一个指令可以使用多次。

3、例子
drawable/vector.xml

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="200dp"
    android:height="200dp"
    android:viewportWidth="110"
    android:viewportHeight="110">
    <group
        android:name="test"
        android:pivotX="55"
        android:pivotY="55">
        <path
            android:pathData="M 26,50
                              a 25,25,0,0,0,25,25"
            android:strokeWidth="2"
            android:strokeColor="@android:color/holo_blue_bright" />
    </group>
</vector>

animator/anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="5000"
        android:interpolator="@android:anim/overshoot_interpolator"
        android:propertyName="rotation"
        android:repeatCount="3"
        android:startOffset="-1"
        android:valueFrom="0"
        android:valueTo="360" />
</set>

drawable/animated_vector.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/vector">
    <target
        android:name="test"
        android:animation="@animator/anim" />
</animated-vector>

layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <ImageView
        android:id="@+id/image_view"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:src="@drawable/animated_vector" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button"
        android:text="button" />
</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(v -> {
            ImageView imageView = findViewById(R.id.image_view);
            AnimatedVectorDrawable animationDrawable = (AnimatedVectorDrawable)imageView.getDrawable();
            animationDrawable.start();
        });
    }

属性动画参考链接

https://blog.csdn.net/harvic880925/article/details/50598322

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

馮贰爺

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

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

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

打赏作者

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

抵扣说明:

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

余额充值