我尝试使用DashPathEffect制作路径动画。必须能够使用按钮多次重播它。
基于http://www.curious-creature.org/2013/12/21/android-recipe-4-path-tracing/
我的问题是,动画在前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:
<Button
android:id="@+id/startTest"
android:layout_width="200dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_height="60dp" />
<com.example.ivanschuetzd.myapplication.Test
android:id="@+id/test"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#000000"
/>
有什么想法吗?或者可能采用不同的方法来制作具有任意路径的这种动画?谢谢!
答案 0 :(得分:6)
刚刚找到了解决方案。 显然问题是DashPathEffect有点错误的硬件加速。 只需致电
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
在您的视图中应该修复它。