Android绘制动画线

Sas*_*uke 19 graphics animation android canvas path

我目前正在使用图形和路径,我可以成功地显示我想要的任何内容.

但是我不想直接在SurfaceView上画一条线,而是想在动画中逐步绘制它.

到目前为止我所做的是创建一个Path然后使用PathMeasure沿路径逐步检索坐标.这基本上是我到目前为止所做的

PathMeasure pm = new PathMeasure(myPath, false);

    float position = 0;
    float end = pm.getLength();
    float[] coord = {0,0,0,0,0,0,0,0,0};

    while (position < end){
        Matrix m = new Matrix();
        // put the current path position coordinates into the matrix
        pm.getMatrix(position, m, PathMeasure.POSITION_MATRIX_FLAG | PathMeasure.TANGENT_MATRIX_FLAG);
        // put the matrix data into the coord array (coord[2] = x and coord[5] = y)
        m.getValues(coord);
        ????
        position += 1;

    }
Run Code Online (Sandbox Code Playgroud)

问号是我被困住的地方.我想逐步绘制路径,并在屏幕上看到它的动画.我在互联网上找不到关于它的很多信息,所以如果你已经遇到过同样的情况,任何线索都会非常感激.我想要创建的最终效果就像铅笔自动逐渐绘制文本.

sku*_*erk 15

每次你想要绘制更多的路径时,你可以使用ObjectAnimator类来回调你的一个类的方法,而不是创建一个for循环.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,只需调用init()开始动画,就像这样(或者如果你希望它在视图膨胀时立即启动,则将init()调用放在构造函数中):

PathView path_view = (PathView) root_view.findViewById(R.id.path);
path_view.init();
Run Code Online (Sandbox Code Playgroud)

也看到这个问题,在这里,和这个例子中,我已经基于我的代码.

  • 我无法理解:你在哪里使用间隔?你为什么要编码??? (2认同)

von*_*ono 5

我刚刚解决了这个问题,在这里我做了什么:

private float[] mIntervals = { 0f, 0f };
private float drawSpeed = 2f;
private int currentPath = -1;
private PathMeasure mPathMeasure = new PathMeasure();
private ArrayList<Path> mListPath = new ArrayList<Path>(this.pathCount);


@Override
protected void onDraw(Canvas canvas) {
   if (mIntervals[1] <= 0f && currentPath < (pathCount - 1)) {
     // Set the current path to draw
     // getPath(int num) a function to return a path.
     Path newPath = this.getPath(mListPath.size());
     this.mListPath.add(newPath);
     this.mPathMeasure.setPath(newPath, false);
     mIntervals[0] = 0;
     mIntervals[1] = this.mPathMeasure.getLength();
   }

  if (mIntervals[1] > 0) {
     // draw the previous path
     int last = this.mListPath.size();
     for (int i = 0; i < last; i++) {
        canvas.drawPath(this.mListPath.get(i), mPaint);
     }
     // partially draw the last path
     this.mPaint.setPathEffect(new DashPathEffect(mIntervals, 0f));

     canvas.drawPath(this.mListPath.get(last), mPaint);

     // Update the path effects values, to draw a little more
     // on the path.
     mIntervals[0] += drawSpeed;
     mIntervals[1] -= drawSpeed;

     super.invalidate();
  } else {
     // The drawing have been done, draw it entirely
     for (int i = 0; i < this.mListPath.size(); i++) {
        canvas.drawPath(this.mListPath.get(i), mPaint);
     }
  }
}
Run Code Online (Sandbox Code Playgroud)

这个例子是对我所做的改编(简化例子).希望你能理解它.由于我刚刚使这个功能正常工作,它缺乏优化和类似的东西.

希望它会有所帮助;-)