Android 动画

补间动画
通过平移,旋转,渐变,缩放等操作实现动画效果。和属性动画不同的是,属性动画会改变View的位置,而补间动画没有改变View的真正位置。如下:
xml布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.yeliang.animation.MainActivity">

    <Button

        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="startAnimation"
        android:text="Hello World!"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="210dp"
        android:id="@+id/button" />
</RelativeLayout>

Activity

public class MainActivity extends AppCompatActivity {

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

    public void startAnimation(View view){
        Animation animation = AnimationUtils.loadAnimation(this,R.anim.translate);
        animation.start();
        view.startAnimation(animation);
    }


}

xml动画

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fillAfter="true"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="30%p"
    //表示屏幕的30%
    android:toYDelta="30%p">
</translate>

每次点击button最开始的位置才会响应,点击button移动后的位置并没有反应。运行效果:
这里写图片描述

属性动画
修改Activity中的代码后
1 在x轴方向上平移

 int position = 0;

    public void startAnimation(View view) {
        position += 100;
        //每次平移的坐标为在x方向上加100
        view.setTranslationX(position);
    }

点击button每次移动后的位置,运行效果:
这里写图片描述

2 在x轴方向上相对于原始位置平移

public void startAnimation(View view) {
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "translationX", 0f, 300f);

        objectAnimator.setDuration(1000);
        objectAnimator.start();
    }

这里写图片描述

3 在y轴方向上相对于原始位置平移

  public void startAnimation(View view) {
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "translationY", 0f, 300f);
        objectAnimator.setDuration(1000);
        objectAnimator.start();
    }

这里写图片描述

4 围绕x轴翻转

 public void startAnimation(View view) {
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "rotationX", 0f, 360f);
        objectAnimator.setDuration(1000);
        objectAnimator.start();
    }

这里写图片描述

5 通过ObjectAnimator,动画执行过程中会多次回调AnimatorUpdateListener接口中的onAnimationUpdate()方法。

public void startAnimation(final View view) {
        //可以看出 第三个参数即使不传也能执行默认动画效果
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "woca", 0f, 100f);
        objectAnimator.setDuration(500);
        objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                animation.getAnimatedFraction();
                float value = (float) animation.getAnimatedValue();

                view.setScaleX(0.5f + value / 200); //0.5f-1.5f
                view.setScaleY(0.5f + value / 200); //0.5f-1.5f
            }
        });

        //动画执行状态的回调,这里未实现。
        objectAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {

            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }
        });

        objectAnimator.start();
    }

这里写图片描述
怎么样,这效果有没有突然菊花一紧的感觉?

6 通过ValueAnmator,动画执行过程中会多次回调AnimatorUpdateListener接口中的onAnimationUpdate()方法。

 public void startAnimation(final View view) {
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 200f);
        valueAnimator.setDuration(500);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                animation.getAnimatedFraction();//动画执行百分比 这里没用到

                float value = (float) animation.getAnimatedValue();
                view.setScaleX(0.5f + value / 400); //0.5f-1
                view.setScaleY(0.5f + value / 400); //0.5f-1
            }
        });

        valueAnimator.start();
    }

这里写图片描述

7 ObjectAnimator和PropertyValuesHolder来实现多个动画的组合

 public void startAnimation(final View view) {
        PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("alpha", 1f, 0.7f, 1f);
        PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0.7f, 1f);
        PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0.7f, 1f);
        PropertyValuesHolder holder4 = PropertyValuesHolder.ofFloat("translationX",0f, 300f);
        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(view, holder1, holder2, holder3, holder4);
        objectAnimator.setDuration(1000);
        objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float animatedValue = (float) animation.getAnimatedValue();
                long playTime = animation.getCurrentPlayTime();
                Log.i("MainActivity", "animatedValue=" + animatedValue + "-----playTime=" + playTime);

            }
        });

        objectAnimator.start();
    }

这里写图片描述

根据下面的打印结果可以得出,动画从1-0.7和从0.7到1执行的事件相等。也就是说从一个动画过程到另一个动画过程经历的时间相等。

MainActivity: animatedValue=0.71507335-----playTime=518
MainActivity: animatedValue=1.0-----playTime=1006

8 通过ObjectAnimator和AnimatorSet实现动画的组合

  public void startAnimation(final View view) {
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(view,"alpha",1f,0.7f,1f);
        ObjectAnimator animator2 =ObjectAnimator.ofFloat(view,"scaleX",1f,0.7f,1f);
        ObjectAnimator animator3 =ObjectAnimator.ofFloat(view,"scaleY",1f,0.7f,1f);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(1000);
//        animatorSet.play(animator1);//执行单个动画
        animatorSet.playTogether(animator1,animator2,animator3);//同时执行
//        animatorSet.playSequentially(animator1,animator2,animator3);//依次执行
        animatorSet.start();
    }

这里写图片描述

9 通过设置插值器,来获得某一瞬时时间点的坐标

public void startAnimation(final View view) {
        ValueAnimator valueAnimator = new ValueAnimator();
        valueAnimator.setDuration(4000);
        valueAnimator.setObjectValues(new PointF(0, 0));

        //插值器
        valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {
            @Override
            public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
                //拿到每一个时间点的坐标
                PointF pointF = new PointF();
                pointF.x = 100f * (fraction * 4);
                pointF.y = 0.5f * 50f * (fraction * 4) * (fraction * 4);
                return pointF;
            }
        });

        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                PointF pointF = (PointF) animation.getAnimatedValue();
                //这是View的坐标
                view.setX(pointF.x);
                view.setY(pointF.y);
            }
        });
        valueAnimator.start();
    }

这里写图片描述

加速器效果
1 匀加速

 public void startAnimation(final View view) {
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "translationY", 0f, 400f);
        objectAnimator.setDuration(500);

        //设置加速器
        objectAnimator.setInterpolator(new AccelerateInterpolator(3));
        objectAnimator.start();
    }

这里写图片描述
2 加速度先变大再变小

objectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

这里写图片描述
3 向上有个回弹效果

 objectAnimator.setInterpolator(new AnticipateInterpolator(8));

这里写图片描述
4 向下有个回弹 下落到最后时再向前

objectAnimator.setInterpolator(new OvershootInterpolator());

这里写图片描述

5 上下回弹多次

oa.setInterpolator(new CycleInterpolator(4));

这里写图片描述
6 模仿物理回弹效果

objectAnimator.setInterpolator(new BounceInterpolator());

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值