Android基础篇-属性动画(Property Animation)

效果图:
这里写图片描述

属性动画(Property Animation):这个是在Android 3.0中才引进的,它更改的是对象的实际属性,在View Animation(Tween Animation)中,其改变的是View的绘制效果,真正的View的属性保持不变,比如无论你在对话中如何缩放Button的大小,Button的 有效点击区域还是没有应用动画时的区域,其位置与大小都不变。而在Property Animation中,改变的是对象的实际属性,如Button的缩放,Button的位置与大小属性值都改变了。而且Property Animation不止可以应用于View,还可以应用于任何对象。Property Animation只是表示一个值在一段时间内的改变,当值改变时要做什么事情完全是你自己决定的。

为什么使用属性动画(Property Animation)?
因为它可以改变对象的属性,能产生更强大的动画。

Property Animation相关类:

1.ValueAnimator:包含Property Animation动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等

2.ObjectAnimator :继承自ValueAnimator,要指定一个对象及该对象的一个属性,当属性值计算完成时自动设置为该对象的相应属性。实际应用中一般都会用ObjectAnimator来改变某一对象的某一属性

但用ObjectAnimator有一 定的限制,要想使用ObjectAnimator,应该满足以下条件:
对象应该有一个setter函数:set(驼峰命名法),就是该对象必须要有属性,并能为其设置values。
为了获得当前值,该对象要有相应属性的getter方 法:get,如果有getter方法,其应返回值类型应与相应的setter方法的参数类型一致。
如果上述条件不满足,则不能用ObjectAnimator,应用ValueAnimator代替。

3.AnimatorSet :提供了一个把多个动画组合成一个组合的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等。

4.AnimatorInflater :用与加载属性动画的xml文件

5.TypeEvalutors: 类型估值,主要用于设置动画操作属性的值

android提供了以下几个evalutor:
IntEvaluator:属性的值类型为int;
FloatEvaluator:属性的值类型为float;
ArgbEvaluator:属性的值类型为十六进制颜色值;

6.TimeInterplator:time interplator定义了属性值变化的方式,如线性均匀改变,开始慢然后逐渐快等。在Property Animation中是TimeInterplator,在View Animation中是Interplator,这两个是一样的,在3.0之前只有Interplator,3.0之后实现代码转移至了 TimeInterplator。Interplator继承自TimeInterplator,内部没有任何其他代码。

android提供了以下Interplator:

AccelerateInterpolator      开始时慢中间加速
DecelerateInterpolator       开始时快然后减速
AccelerateDecelerateInterolator  开始结束时慢,中间加速
AnticipateInterpolator       先向相反方向改变一段再加速播放
AnticipateOvershootInterpolator  反向加超越,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
BounceInterpolator        跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
CycleIinterpolator         循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2 * mCycles * Math.PI * input)
LinearInterpolator         线性均匀改变
OvershottInterpolator       超越,最后超出目的值然后缓慢改变到目的值

相关属性:
1.Duration动画的持续时间,默认300ms。

2.Time interpolation:插值,就是Tween动画中的Interpolation

4.Repeat count and behavior:重复次数、以及重复模式;可以定义重复多少次;重复时从头开始,还是反向。

5.Animator sets: 动画集合,你可以定义一组动画,一起执行或者顺序执行。

6.Frame refresh delay:帧刷新延迟,对于你的动画,多久刷新一次帧;默认为10ms,但最终依赖系统的当前状态;基本不用管

最后给出源码:
activity_main:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/ll_linear"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/iv_image"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:src="@drawable/seven" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent"
        android:text="改变整个布局的颜色"
        android:onClick="btn_ll"/>
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:text="ObjectAnimator"
            android:onClick="btn_object"/>


    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:text="ValueAnimator"
            android:onClick="btn_value"/>
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:text="AnimatorSet"
            android:onClick="btn_set"/>
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:text="自定义View"
            android:onClick="btn_custom"/>

    </LinearLayout>

</LinearLayout>

动画xml:
res/animator/object_animator

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:interpolator="@android:anim/linear_interpolator"
    android:propertyName="backgroundColor"
    android:repeatCount="infinite"
    android:repeatMode="restart"
    android:valueFrom="#ff0000"
    android:valueTo="#0000ff"
    android:valueType="intType" >

    <!-- android:propertyName 设置属性动画名称 -->
    <!-- android:repeatCount="infinite"  设置循环次数为循环 -->
    <!-- android:interpolator  设置动画的播放速度 -->
    <!-- android:repeatMode="restart"   设置替换模式,默认为顺序播放  reverse 倒序播放 -->
    <!-- android:valueFrom 设置播放动画的起始的状态 -->
    <!-- android:valueTo 设置播放动画的结束状态 -->
    <!-- android:valueType  设置播放的类型 -->

</objectAnimator>

res/animator/object_rotate

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="rotation" 
    android:interpolator="@android:anim/cycle_interpolator"
    android:duration="5000"
    android:repeatCount="infinite"
    android:valueFrom="0.0"
    android:valueTo="720"
    android:valueType="floatType"
    android:repeatMode="reverse">
    

</objectAnimator>

自定义View动画类

import android.animation.AnimatorInflater;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.view.View;

public class MyAnimator extends View {

	public MyAnimator(Context context) {
		super(context);
		ObjectAnimator oAnimator = (ObjectAnimator) AnimatorInflater
				.loadAnimator(context, R.animator.object_animator);
		// 设置动画计算器,解析当前的颜色ARGB
		oAnimator.setEvaluator(new ArgbEvaluator());
		// 设置将当前动画加载至对应的控件上
		oAnimator.setTarget(this);
		// 播放动画
		oAnimator.start();
	}
}

MainActivity:


import android.os.Bundle;
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.Activity;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends Activity {

    private float windowHeight;
    private float windowWidth;
    private LinearLayout ll_linearLayout;
    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.iv_image);
        // 获取屏幕测量工具类
        DisplayMetrics oDisplayMetrics = new DisplayMetrics();
        // 根据通过管理者获得屏幕显示的高度  Metrics  度量
        getWindowManager().getDefaultDisplay().getMetrics(oDisplayMetrics);
        windowHeight = oDisplayMetrics.heightPixels;
        windowWidth = oDisplayMetrics.widthPixels;
    }
    public void btn_ll(View view){
        ll_linearLayout = (LinearLayout) findViewById(R.id.ll_linear);
        ObjectAnimator animator = (ObjectAnimator) AnimatorInflater
                .loadAnimator(this, R.animator.object_animator);
        //Evaluator   请求
        animator.setEvaluator(new ArgbEvaluator());
        //target表示当前动画所承载的控件
        animator.setTarget(ll_linearLayout);
        //动画开始
        animator.start();
    }

    public void btn_object(View view){
        objectAnimator_java();
        //objectAnimator_xml();
    }

    /**
     * 使用Java代码实现属性动画
     * */
    private void objectAnimator_java() {
        // float...values 这个是可变的数组类型
        ObjectAnimator animator = ObjectAnimator.ofFloat(imageView,
                "rotationY", 0.0f, 360.0f);
        animator.setDuration(5000);
        animator.setInterpolator(new LinearInterpolator());
        // 循环次数
        animator.setRepeatCount(2);
        // 循环模式
        animator.setRepeatMode(0);
        // 播放动画
        animator.start();

    }

    private void objectAnimator_xml() {
        ObjectAnimator animator = (ObjectAnimator) AnimatorInflater
                .loadAnimator(this, R.animator.object_rotate);
        animator.setTarget(this);
        animator.start();
    }

    public void btn_value(View view){
        valueAnimator_Y_java();
//        valueAnimator_X_java();
    }
    /*
    * 自由落体动画
    */
    private void valueAnimator_Y_java() {
        ValueAnimator animator = ValueAnimator.ofFloat(0.0f, windowHeight
                - imageView.getHeight());
        animator.setDuration(5000);
        animator.setTarget(imageView);
        animator.start();
        // 动画改变监听器
        animator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                imageView.setTranslationY((Float) animation.getAnimatedValue());
            }
        });
    }

    /**
     * 水平运动
     */
    private void valueAnimator_X_java() {
        ValueAnimator animator = ValueAnimator.ofFloat(0.0f, windowWidth
                - imageView.getWidth());
        animator.setDuration(5000);
        animator.setTarget(imageView);
        animator.start();
        // 动画改变监听器
        animator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                imageView.setTranslationX((Float) animation.getAnimatedValue());
            }
        });
    }

    public void btn_set(View view){
        animator_set();
//        animator_set_order();
    }

    private void animator_set() {
        // target表示当前动画所承载的控件
        // propertyName当前所实现的什么动画
        ObjectAnimator animator = ObjectAnimator.ofFloat(imageView,
                "rotationX", 0.0f, 360.0f);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView, "scaleY",
                1.0f, 2.0f);
        AnimatorSet oSet = new AnimatorSet();
        oSet.playTogether(animator, animator2);
        oSet.setDuration(5000);
        oSet.start();

    }

    private void animator_set_order() {
        ObjectAnimator animator = ObjectAnimator.ofFloat(imageView,
                "rotationX", 0.0f, 360.0f);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView, "scaleY",
                1.0f, 2.0f);
        ObjectAnimator animator3 = ObjectAnimator.ofFloat(imageView,
                "rotationY", 0.0f, 360.0f);
        ObjectAnimator animator4 = ObjectAnimator.ofFloat(imageView, "scaleX",
                1.0f, 2.0f);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.play(animator3).with(animator).after(animator4)
                .after(animator2);
        animatorSet.setDuration(7000);
        animatorSet.start();
    }

    public void btn_custom(View view){
         //实例化自定义View
         MyAnimator myAnimator=new MyAnimator(this);
         //设置控件的高宽
         LinearLayout.LayoutParams params=new LinearLayout.LayoutParams
         (LinearLayout.LayoutParams.MATCH_PARENT,
         LinearLayout.LayoutParams.MATCH_PARENT);
         //设置控件的间距
         params.setMargins(5, 5, 5, 5);
         //将设置的布局参数加至view
         view.setLayoutParams(params);
         //将自定义控件添加至线性布局
         ll_linearLayout.addView(myAnimator);
    }

}

属性动画到此结束,还不会的小伙伴赶快敲起来吧。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

有头发的猿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值