zoukankan      html  css  js  c++  java
  • android属性动画之ValueAnimator

          楼主前段时间做一个android项目,其中一个需求是需要制作一个动画,但是之前楼主没接触过android动画,所以在网上搜了下,并且也有人推荐可以试下用属性动画,所以我就百度了下属性动画怎么用,并顺便写下valueAnimator的用法。

      其实valueAnimator用起来非常非常简单:

        首先先讲下核心函数:

        

            ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(Math.min(((getRight()-getLeft()))/2,(getBottom()-getTop())/2)), startPoint, endPoint);
    
            anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    currentPoint = (Point) animation.getAnimatedValue();
                    invalidate();
                }
            });
            anim.setRepeatMode(ValueAnimator.RESTART);
            anim.setRepeatCount(1000);
            
            anim.start();

        首先对这几行代码进行一个简单的解释,第一行为初始化一个valueAnimator类,然后其中第一个参数是一个事先定以后好的类,这个在后边具体解释,,然后第二个第三个参数分别代表起始位置和结束位置,当然这个也可以不写,通过其他方式也可传入进去,这个也放在后边解释。

        第二行代码,是用来添加监听器,这个监听器作用则是实时的获取当前坐标,赋值给currentPoint(这个对象是自己声明的,这个对象可以在全局中声明和使用)。

        然后invalidate()则是更新当前图形坐标。

        setRepeatMode(),则是选择动画执行的模式,有两种模式,即ValueAnimator.RESTART(重复),ValueAnimator.REVERSE(反方向重复)

        anim.setRepeatCount(1000)设置重复次数。

        anim.setDuration(40000);设置每次执行时间。

        那这个说完了,则把刚才的遗留问题解决了,下边贴出那个类的代码

        

    public class PointEvaluator implements TypeEvaluator {
        float r;
        public PointEvaluator(float r)
        {
            this.r = r;
        }
    
        @Override
        public Object evaluate(float fraction, Object startValue, Object endValue) {
            Point startPoint = (Point) startValue;
            Point endPoint = (Point) endValue;
            float x = new Float(startPoint.getX() - Math.sin(fraction* Math.PI*2*20)*r);
            float y = new Float(startPoint.getY() - (r - Math.cos(fraction* Math.PI*2*20) * r) );
            Point point = new Point(x, y);
            return point;
        }
    
    }

        这个类中,最重要的是evaluate函数,这个函数的作用是计算动画的过程,其中fraction参数的值是从0-1,然后动画执行一次,fraction从0到1执行一次。因此,在这个函数中,通过fraction函数来计算当前的坐标,因此要利用好这个fraction参数。这里的两个参数startValue和endValue则是刚才上述讲的传入的两个参数,为什么说可传可不传,是因为你也可以通过对这个类添加构造函数,然后传进来初始和结束值。

        然后这个类怎么用呢?

        看下方代码:

        

    public class MyAnimView extends View {
    
        public static final float RADIUS = 10f;
    
        private Point currentPoint;
    
        private Paint mPaint;
    
        public MyAnimView(Context context, AttributeSet attrs) {
    
            super(context, attrs);
            Log.e("view","-------------构造函数");
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setColor(Color.GREEN);
            mPaint.setStrokeWidth(5l);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            if (currentPoint == null) {
                currentPoint = new Point(RADIUS, RADIUS);
                drawCircle(canvas);
                startAnimation();
            } else {
                drawCircle(canvas);
            }
        }
    
        private void drawCircle(Canvas canvas) {
            float x = currentPoint.getX();
            float y = currentPoint.getY();
            canvas.drawLine((getLeft()+getRight())/2, (getBottom()+getTop())/2,x,y,mPaint);
        }
    
        public void startAnimation() {
    
            Point startPoint = new Point((getLeft()+getRight())/2, (getBottom()+getTop())/2+ Math.min(((getRight()-getLeft()))/2,(getBottom()-getTop())/2));
            Point endPoint = startPoint;
            Log.e("myAnim","x="+(getLeft()+getRight())/2+"    y="+(getTop()+getBottom())/2);
            Log.e("myAnim","left="+getLeft()+"   right="+getRight()+"    top="+getTop()+"   botton"+getBottom());
    
            ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(Math.min(((getRight()-getLeft()))/2,(getBottom()-getTop())/2)), startPoint, endPoint);
    
            anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    currentPoint = (Point) animation.getAnimatedValue();
                    invalidate();
                }
            });
            anim.setRepeatMode(ValueAnimator.RESTART);
            anim.setRepeatCount(1000);
            anim.setDuration(4000);
            anim.start();
        }
    
    }

        通过自定义view,然后在其中ondraw中做开始动画,然后画出具体的图形,则大功告成。

        

  • 相关阅读:
    主线程到子线程的相互切换
    IOS通过OTA部署App
    IOS应用之间调用
    静态库详解
    ObjectC的函数调用机制详解消息
    iOS6新特征:参考资料和示例汇总
    杭电acm2025
    杭电acm2051
    杭电acm1009
    杭电acm2099
  • 原文地址:https://www.cnblogs.com/cmai/p/7295868.html
Copyright © 2011-2022 走看看