Android 带DashPathEffect动画的奇怪闪烁

Android 带DashPathEffect动画的奇怪闪烁,android,animation,Android,Animation,我正在尝试使用DashPathEffect制作路径动画。必须能够使用按钮多次重播 基于 我的问题是,动画在前10次左右运行良好,然后路径变得疯狂,开始闪烁,以相反的顺序运行,或者在不需要的地方结束 我记录了动画的值和传递到路径的值,它们看起来是正确的,没有跳跃或任何奇怪的事情。我不知道是什么导致了这些问题 代码如下: public class Test extends View { private float mDrag; private MyPath path1;

我正在尝试使用DashPathEffect制作路径动画。必须能够使用按钮多次重播

基于

我的问题是,动画在前10次左右运行良好,然后路径变得疯狂,开始闪烁,以相反的顺序运行,或者在不需要的地方结束

我记录了动画的值和传递到路径的值,它们看起来是正确的,没有跳跃或任何奇怪的事情。我不知道是什么导致了这些问题

代码如下:

public class Test extends View {

    private float mDrag;

    private MyPath path1;

    private int mDuration;

    //just some shape
    private static Path makeDragPath(int radius) {
        Path p = new Path();
        RectF oval = new RectF(10.0f, 10.0f, radius * 2.0f, radius * 2.0f);

        float cx = oval.centerX();
        float cy = oval.centerY();
        float rx = oval.width() / 2.0f;
        float ry = oval.height() / 2.0f;

        final float TAN_PI_OVER_8 = 0.414213562f;
        final float ROOT_2_OVER_2 = 0.707106781f;

        float sx = rx * TAN_PI_OVER_8;
        float sy = ry * TAN_PI_OVER_8;
        float mx = rx * ROOT_2_OVER_2;
        float my = ry * ROOT_2_OVER_2;

        float L = oval.left;
        float T = oval.top;
        float R = oval.right;
        float B = oval.bottom;

        p.moveTo(R, cy);
        p.quadTo(      R, cy + sy, cx + mx, cy + my);
        p.quadTo(cx + sx, B, cx, B);
        p.quadTo(cx - sx,       B, cx - mx, cy + my);
        p.quadTo(L, cy + sy, L, cy);
        p.quadTo(      L, cy - sy, cx - mx, cy - my);
        p.quadTo(cx - sx, T, cx, T);


        return p;
    }




    public Test(Context context, AttributeSet attrs) {
        super(context, attrs);

        init();
    }




    public static class MyPath {
        private static final Region sRegion = new Region();
        private static final Region sMaxClip = new Region(
                Integer.MIN_VALUE, Integer.MIN_VALUE,
                Integer.MAX_VALUE, Integer.MAX_VALUE);

        final Path path;
        final Paint paint;
        final float length;
        final Rect bounds;

        MyPath(Path path, Paint paint) {
            this.path = path;
            this.paint = paint;

            PathMeasure measure = new PathMeasure(path, false);
            this.length = measure.getLength();

            sRegion.setPath(path, sMaxClip);
            bounds = sRegion.getBounds();
        }


    }


    private static PathEffect createPathEffect2(float pathLength, float phase) {

        //I modified the original approach using phase, to use only path instead because later I want to animate also the starting point and phase alone is not enough for this

        float full = phase * pathLength;

        return new DashPathEffect(new float[] {full, Float.MAX_VALUE}, //on, off
                0);
    }

    ObjectAnimator current;


    public void startAnim() {
        if (current != null) {
            current.cancel();
        }

        current = ObjectAnimator.ofFloat(Test.this, "drag", 0.0f, 1.0f).setDuration(mDuration);
        current.start();
    }

    private void scalePath(Path path, float scale) {
        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(scale, scale);
        path.transform(scaleMatrix);
    }

    private void init() {

        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);

        paint.setStrokeWidth(8.0f);
        paint.setColor(0xffffffff);

        mDuration = 3000;

        Path p1 = makeDragPath(40);
        scalePath(p1, 3);

        path1 = new MyPath(p1, paint);


        startAnim();
    }

    public float getDrag() {
        return mDrag;
    }

    public void setDrag(float drag) {

        mDrag = drag;

        path1.paint.setPathEffect(createPathEffect2(path1.length, mDrag));

        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawColor(Color.BLACK); //doesn't help

        canvas.drawPath(path1.path, path1.paint);
    }

}
在我的活动中:

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

    final Test test = (Test)findViewById(R.id.test);

    Button button = (Button)findViewById(R.id.startTest);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            test.startAnim();
        }
    });
}
xml:



有什么想法吗?或者是用一种不同的方法来制作这种具有任意路径的动画?谢谢

刚刚找到了解决办法。 显然,问题在于硬件加速有点像DashPathEffect的bug。 就打电话

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

在您看来,这应该可以解决问题。

感谢您提供的解决方案。你能告诉我你是怎么找到解决办法的吗?你救了我的命你是个传奇人物。英雄。
setLayerType(View.LAYER_TYPE_SOFTWARE, null);