Android中ValueAnimator的使用

来源:互联网 发布:英文翻译发音软件 编辑:程序博客网 时间:2024/06/05 04:10

写在前面的话

这个时代,新物种正在生长,新边疆正在延伸。做别人的小兵,还是做自己的将军,你选。

前言

  • 今天给大家带来的是ValueAnimator的相关用法,下面先给大家看下效果图。

效果图

这里写图片描述

动画介绍

这里我们写了两个位移动画,分别是城市交换动画和日期位移动画,下面我们将通过代码详细介绍下两个动画的具体实现,从而理解valueAnimator的相关使用。

城市交换动画

  • 左边城市:startCityTextView
  • 右边城市:endCityTextView
  • 首先获取startCityTextView和endCityTextView的x坐标,因为是水平方向的移动。
    1. startX:左边城市的横坐标
    2. endX:右边城市的横坐标
    private int startX;    private int endX;    private void getLocation() {        int[] startLocation = new int[2];        startCityTextView.getLocationOnScreen(startLocation);        int[] endLocation = new int[2];        endCityTextView.getLocationOnScreen(endLocation);        startX = startLocation[0];        endX = endLocation[0];    }

左边城市动画

  • 移动距离
final int moveX = endX - startX + endCityTextView.getWidth() - startCityTextView.getWidth();
  • 动画代码
ValueAnimator startCityAnimation = ValueAnimator.ofInt(0, moveX).setDuration(500);        startCityAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                int value = (int) animation.getAnimatedValue();                startCityTextView.layout(startX + value, startCityTextView.getTop(), startX + value + startCityTextView.getWidth(), startCityTextView.getBottom());            }        });        startCityAnimation.start();

右边城市动画

  • 移动距离
int rightMoveX = endX - startX;
  • 动画代码
ValueAnimator endCityAnimator = ValueAnimator.ofInt(0, rightMoveX).setDuration(500);        endCityAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                int value = (int) animation.getAnimatedValue();                endCityTextView.layout(endX - value, endCityTextView.getTop(), endX + endCityTextView.getWidth() - value, endCityTextView.getBottom());            }        });        endCityAnimator.start();

调换view位置

最后需要在动画结束后调换view的位置, 使startCityTextView变为endCityTextView,这样下次动画执行时位置坐标才正确。

endCityAnimator.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {            }            @Override            public void onAnimationEnd(Animator animation) {                TextView flagTextView = startCityTextView;                startCityTextView = endCityTextView;                endCityTextView = flagTextView;            }            @Override            public void onAnimationCancel(Animator animation) {            }            @Override            public void onAnimationRepeat(Animator animation) {            }        });

日期位移动画

透明度动画

  • isSingleLine:判断是点击的单程还是往返
    1. 单程:透明度由1变到0,通过重写ObjectAnimator的setEvaluator方法,其中fraction的变化是由0到1
    2. 往返:透明度从0变到1
ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(rightLayout, View.ALPHA, 0, 1.0f).setDuration(1000);        if (isSingleLine) {            alphaAnimator.setEvaluator(new TypeEvaluator<Float>() {                @Override                public Float evaluate(float fraction, Float startValue, Float endValue) {                    return 1 - fraction;                }            });        }        alphaAnimator.start();

位移动画

动画分析:

  • screenWidth 屏幕宽度
    1. 往返:把view从screenWidth+view.getWidth()的位置移动到screenWidth-view.getWidth的位置,移动距离:view.getWidth()
    2. 单程:把view移出到screenWidth和view.getWidth()之和的位置,移动距离:view.getWidth()
  • 获取屏幕宽度
    private int getScreenWidth() {        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();        return displayMetrics.widthPixels;    }
  • 动画代码
ValueAnimator animator = ValueAnimator.ofFloat(0, rightLayout.getWidth()).setDuration(500);        animator.setEvaluator(isSingleLine ? new ATFlightEvaluator() : new FloatEvaluator());        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                float value = (float) animation.getAnimatedValue();                int screenWidth = getScreenWidth();                rightLayout.layout(screenWidth - (int) value, rightLayout.getTop(), screenWidth + rightLayout.getWidth() - (int) value, rightLayout.getBottom());            }        });        animator.start();


  • ATFlightEvalutor

这里isSingleLine时我们设置其Evaluator为我们自定义的ATFlightEvalutor,实现TypeEvaluator接口并重写其evaluate方法,这样我们获取到动画变化中的value值就是由view.getWidth()—>0变化的。
  1. startValue: 0
  2. endValue: view.getWidth()
  3. fraction: 动画的变化率0—>1
  4. 其最后返回的值就是我们使用animation.getAnimatedValue()获取的值。
public class ATFlightEvaluator implements TypeEvaluator<Float> {    @Override    public Float evaluate(float fraction, Float startValue, Float endValue) {        return endValue - fraction * (endValue - startValue);    }}

总结

以上就是我们通过valueAnimator实现的两个小实例,有兴趣的童鞋可以研究下代码,另外有不明白的地方可以在下面留言或者发邮件kuangxiaoguo@163.com。

0 0
原创粉丝点击