Android drawing an animated line

前端 未结 4 537
时光说笑
时光说笑 2020-12-23 10:24

I\'m currently working with graphics and paths, and I can successufully display whatever I want.

But instead of drawing a line directly on my SurfaceView, I\'d like

4条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-23 11:11

    Instead of creating a for loop, you can use the ObjectAnimator class to callback to one of your class's methods every time you'd like to draw a bit more of the path.

    import android.animation.ObjectAnimator;
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.DashPathEffect;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.PathEffect;
    import android.graphics.PathMeasure;
    import android.util.AttributeSet;
    import android.view.View;
    import android.util.Log;
    
    public class PathView extends View
    {
        Path path;
        Paint paint;
        float length;
    
        public PathView(Context context)
        {
            super(context);
        }
    
        public PathView(Context context, AttributeSet attrs)
        {
            super(context, attrs);
        }
    
        public PathView(Context context, AttributeSet attrs, int defStyleAttr)
        {
            super(context, attrs, defStyleAttr);
        }
    
        public void init()
        {
            paint = new Paint();
            paint.setColor(Color.BLUE);
            paint.setStrokeWidth(10);
            paint.setStyle(Paint.Style.STROKE);
    
            path = new Path();
            path.moveTo(50, 50);
            path.lineTo(50, 500);
            path.lineTo(200, 500);
            path.lineTo(200, 300);
            path.lineTo(350, 300);
    
            // Measure the path
            PathMeasure measure = new PathMeasure(path, false);
            length = measure.getLength();
    
            float[] intervals = new float[]{length, length};
    
            ObjectAnimator animator = ObjectAnimator.ofFloat(PathView.this, "phase", 1.0f, 0.0f);
            animator.setDuration(3000);
            animator.start();
        }
    
        //is called by animtor object
        public void setPhase(float phase)
        {
            Log.d("pathview","setPhase called with:" + String.valueOf(phase));
            paint.setPathEffect(createPathEffect(length, phase, 0.0f));
            invalidate();//will calll onDraw
        }
    
        private static PathEffect createPathEffect(float pathLength, float phase, float offset)
        {
            return new DashPathEffect(new float[] { pathLength, pathLength },
                Math.max(phase * pathLength, offset));
        }
    
        @Override
        public void onDraw(Canvas c)
        {
            super.onDraw(c);
            c.drawPath(path, paint);
        }
    }
    

    Then, just call init() to begin the animation, like this (or if you'd like it to start as soon as the view is inflated, put the init() call inside the constructors):

    PathView path_view = (PathView) root_view.findViewById(R.id.path);
    path_view.init();
    

    Also see this question here, and this example, which I've based my code on.

提交回复
热议问题