Android基础——属性动画赏析

经常看一些大神的博客,大多数大神开篇都轻谈一些国内比较专注的事和一些身边琐事,以表自己心情感悟。像我这种菜鸡就直接步入正题吧。毕竟这东西就这么简单。

Android动画效果有位移、缩放。旋转。透明度等。Animation和Animator都都能实现动画效果。下面就和说下这2个不同之处吧

1、传统动画:Animaton系统不断的调用onDraw方法去重绘界面来实现一个动画的效果

public void move(View view){
        TranslateAnimation animation = new TranslateAnimation(0,200,0,0);
        animation.setDuration(1000);
        animation.setFillAfter(true);
        imageView.startAnimation(animation);
}

上断面代码简单实现了imageView的的X轴方向平移了200个像素。虽然实现了这个效果,只是重绘了动画,改变了显示的位子,并没有改变响应事件的位子(可以添加监听事件做测试),所以传统动画并不能做与用户有交互动作的效果,并且不断的调用onDraw方法耗费cpu资源加上只有4种动画效果。并不能满足现在用户的需求。因此谷歌在3.0之后提出了属性动画。

2、属性动画(谷歌3.0之后出来的):Animator,顾名思义,就是操作一个属性的get、set方法去真实的改变一个属性。

   一些常用的API:alpha 透明度, rotation z轴旋转, rotationX x轴旋转,rotationY y轴旋转,translationX x水平偏移

        //第一种
        ObjectAnimator.ofFloat(imageView,"translationY",0F,200F).setDuration(1000).start();
        ObjectAnimator.ofFloat(imageView,"translationX",0F,200F).setDuration(1000).start();
        ObjectAnimator.ofFloat(imageView,"rotation",0F,360F).setDuration(1000).start();
        //第二种
        PropertyValuesHolder p1 =   PropertyValuesHolder.ofFloat("translationY",0F,200F);
        PropertyValuesHolder p2 =   PropertyValuesHolder.ofFloat("translationX",0F,200F);
        PropertyValuesHolder p3 =   PropertyValuesHolder.ofFloat("rotation",0F,360F);
        ObjectAnimator.ofPropertyValuesHolder(imageView,p1,p2,p3);
上面是二种方面实现了图片的动画效果,是什么效果可以自己去敲下,毕竟这么简单。

还有一种就是通过AnimatorSet集合去实现动画的执行顺序

        ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView, "translationY", 0F, 150F);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView,"translationX",0F,150F);
        ObjectAnimator animator3 = ObjectAnimator.ofFloat(imageView,"rotation",0F,180F);
        ObjectAnimator animator4 = ObjectAnimator.ofFloat(imageView,"X",0F,1F);
        AnimatorSet set = new AnimatorSet();
 //       set.playTogether(animator1,animator2,animator3);同事执行
  //      set.playSequentially(animator1,animator2,animator3);案顺序执行
        //先同时执行1和2,然后在执行3
        set.play(animator1).with(animator2);
        set.play(animator3).after(animator2);
        set.play(animator4).after(animator3);
        set.setDuration(1000);
        set.start();
3、如何给一个动画设置监听事件呢?非常简单:

    public void alphaClick(View view){
        ObjectAnimator animator = ObjectAnimator.ofFloat(view,"alpha",0F,1F);

        animator.setDuration(1000);
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                Toast.makeText(MainActivity.this,"anmi end",Toast.LENGTH_SHORT).show();
            }
        });
        animator.start();
    }
点击控件,透明度在1秒的变化,1秒后,打印吐司。

4、接下来我们来实现一个小例子吧,

      XML文件:很简单,就是就是放了7张图片,叠在一起

     

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/image_b"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="5dp"
        android:paddingLeft="5dp"
        android:src="@mipmap/b"
        />
    <ImageView
        android:id="@+id/image_c"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="5dp"
        android:paddingLeft="5dp"
        android:src="@mipmap/c"
        />
    <ImageView
        android:id="@+id/image_d"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="5dp"
        android:paddingLeft="5dp"
        android:src="@mipmap/d"
        />
    <ImageView
        android:id="@+id/image_e"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="5dp"
        android:paddingLeft="5dp"
        android:src="@mipmap/e"
        />
    <ImageView
        android:id="@+id/image_f"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="5dp"
        android:paddingLeft="5dp"
        android:src="@mipmap/f"
        />
    <ImageView
        android:id="@+id/image_g"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="5dp"
        android:paddingLeft="5dp"
        android:src="@mipmap/g"
        />

    <ImageView
        android:id="@+id/image_a"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="5dp"
        android:paddingLeft="5dp"
        android:src="@mipmap/a"
        />

</FrameLayout>

下面是Java代码:也很简单,在onCreat中初始化imageView,并添加到list中,然后设置监听。

package com.dragon.httpdeom.httpdemo;

import android.animation.ObjectAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.BounceInterpolator;
import android.widget.ImageView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
 * Created by Administrator on 2016/8/26 0026.
 */
public class myActivity extends Activity implements View.OnClickListener {
    private int[] res = {R.id.image_a,R.id.image_b,R.id.image_c,R.id.image_d,R.id.image_e,R.id.image_f,R.id.image_g};
    private List<ImageView> imageViewList = new ArrayList<>();
    private boolean flag = true;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activit_my);
        for (int i = 0; i <res.length ; i++) {
            ImageView imageView = (ImageView) findViewById(res[i]);
            imageView.setOnClickListener(this);
            imageViewList.add(imageView);
        }
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.image_a:
                if (flag){
                    startAnim();
                }else {
                    stopAnim();
                }
                break;
            default:
                Toast.makeText(myActivity.this,"click"+ v.getId(),Toast.LENGTH_SHORT).show();
                break;
        }
    }
    private void stopAnim() {
        for (int i = 1; i <res.length ; i++) {
            ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),"translationY",i * 80,0F);
            //设置动画完成时间
           animator.setDuration(500);
            //设置动画开始延迟
           animator.setStartDelay(i * 300);
            //设置动画速度效果,动画是速度interpolator,他可以定义动画的速度变化,从而实现更加复杂的动画效果
           animator.setInterpolator(new BounceInterpolator());
            animator.start();
            flag =true;
        }
    }
    private void startAnim() {
        for (int i = 1; i <res.length ; i++) {
            ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),"translationY",0F,i * 80);
            animator.setDuration(500);
            animator.setInterpolator(new BounceInterpolator());
            animator.setStartDelay(i * 300);
            animator.start();
            flag =false;
        }
    }
}
上面实现的是小球直线效果,直线的效果自己去实现下,这里我贴下扇形的效果图也可以实现小球的扇形效果,如下代码:

        float angle;
        final int r = 380;
        angle = (float) Math.PI / (2 * (res.length - 2));
        for (int i = 1; i < res.length; i++) {
            float xLength = (float) (r * Math.sin((i - 1) * angle));
            float yLength = (float) (r * Math.cos((i - 1) * angle));
            ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageViewList.get(i),
                    "translationX", 0F, -xLength);
            ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageViewList.get(i),
                    "translationY", 0F, -yLength);
            AnimatorSet set = new AnimatorSet();
            set.playTogether(animator1, animator2);
            set.setDuration(500);
            set.setInterpolator(new BounceInterpolator());
            set.setStartDelay(i * 200);
            set.start();
            flag = true;
效果图:

4、ValueAnimator:是ObjetAnimator的父类,ValueAnimator本身并不会作用任何一个属性也不会提供任何一种动画,是一个数值发生器(产生你想要的任何数值)。有了这个值就可以作用控件,比如x值不断增加,形成一个动画,看个例子就明白了:点击button,上面的文本就0增加到100;

  public void ValueClick(View view){
        final Button button = (Button) view;
        ValueAnimator animator = ValueAnimator.ofInt(0,100);
        animator.setDuration(5000);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Integer value = (Integer) animation.getAnimatedValue();
                button.setText(""+value);
            }
        });

其中也可以自定义数值,代码如下。

ValueAnimator animator1  = ValueAnimator.ofObject(new TypeEvaluator<PointF>() {
            @Override
            public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
                float x=(endValue.x-startValue.x)*fraction;
                float y=(endValue.y-startValue.x)*fraction;
                button.setX(x);
                button.setY(y);
                return null;
            }
        },new PointF(1, 1),new PointF(300,300));
        animator1.setDuration(3000);
        animator1.start();

效果图:
 好了,完事!!喜欢交友的朋友可以留言! 




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值