private void setAction(Action action, boolean animate, int rotation) { if (action == null) { return; } this.rotation = rotation; if (currentAction == null) { currentAction = action; currentAction.flipHorizontally(); animationProgress = 1f; UiHelper.postInvalidateOnAnimation(this); return; } if (currentAction.getClass().equals(action.getClass())) { return; } oldAction = currentAction; currentAction = action; if (animate) { animationProgress = 0f; if (ready) { startAnimation(); } else { animateWhenReady = true; } } else { animationProgress = 1f; UiHelper.postInvalidateOnAnimation(this); } }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (currentAction == null) { return; } if (oldAction == null) { updatePath(currentAction); } else { final float inverseProgress = 1f - animationProgress; final float[] current = currentAction.getLineData(); final float[] old = oldAction.getLineData(); final float[] animated = animatedAction.getLineData(); for (int i = 0; i < animated.length; i++) { animated[i] = current[i] * animationProgress + old[i] * inverseProgress; } updatePath(animatedAction); } canvas.rotate( (rotation == ROTATE_CLOCKWISE ? 180f : -180f) * animationProgress, centerX, centerY); canvas.drawPath(path, paint); }
private void transformActions() { if (currentAction != null && !currentAction.isTransformed()) { currentAction.transform(padding, padding, scale, size); } if (oldAction != null && !oldAction.isTransformed()) { oldAction.transform(padding, padding, scale, size); } }
private void startAnimation() { oldAction.flipHorizontally(); currentAction.flipHorizontally(); transformActions(); animatedAction.setLineSegments(currentAction.getLineSegments()); final ObjectAnimator animator = ObjectAnimator.ofFloat(ActionView.this, "animationProgress", 0f, 1f); animator.setInterpolator(BakedBezierInterpolator.getInstance()); animator.setDuration(animationDuration).start(); }
private void updatePath(Action action) { path.reset(); final float[] data = action.getLineData(); // Once we're near the end of the animation we use the action segments to draw linked lines if (animationProgress > 0.95f && !action.getLineSegments().isEmpty()) { for (LineSegment s : action.getLineSegments()) { path.moveTo(data[s.getStartIdx() + 0], data[s.getStartIdx() + 1]); path.lineTo(data[s.getStartIdx() + 2], data[s.getStartIdx() + 3]); for (int i = 1; i < s.indexes.length; i++) { path.lineTo(data[s.indexes[i] + 0], data[s.indexes[i] + 1]); path.lineTo(data[s.indexes[i] + 2], data[s.indexes[i] + 3]); } } } else { for (int i = 0; i < data.length; i += 4) { path.moveTo(data[i + 0], data[i + 1]); path.lineTo(data[i + 2], data[i + 3]); } } }