【问题标题】:Custom timeline for View-Animation?视图动画的自定义时间线?
【发布时间】:2014-10-18 18:52:28
【问题描述】:

我希望能够为标准Android animation 创建时间 的任意输入。例如,我希望输入是来自用户触摸输入的坐标,而不是运行 1 秒的动画。例如,当圆周运动中的位置由幻灯片 A 上的线性输入定义时,我可以通过这种方式创建对象 A 的圆周运动。

粗略的插图:

现在我认为这可以通过在 XML 中定义翻译动画来实现,就像在 /res/anim 下的常规动画一样,但是覆盖来自用户输入控件的时间输入。我不确定也可以使用自定义插值器来完成。无论如何,我不知道动画的设定开始和结束时间。

有人对如何实现这一点有任何建议吗?

编辑:进一步回答几个 cmets:想想用户是否滑动/拖动蓝点。输入之间不发生插值。一旦用户抬起手指,“动画”就会停止。

【问题讨论】:

  • 也许这可以帮助youtube.com/watch?v=JVGg4zPRHNE
  • 动画依赖于时间,除非你发明了时间机器,否则你不能“停止”时间;)
  • 这是真正的动画吗? IE。有什么东西在自己移动吗?还是只有当蓝色圆圈移动时,红色圆圈才会移动 - 在这种情况下,它只是绑定,不应该涉及动画。
  • @nitzanj 仅在蓝色圆圈移动时移动。除非用户采取行动,否则什么都不会发生。你是什​​么意思“操纵”? psink:这也应该回答你的反对意见。
  • 您不应该为此使用动画,而是使用自定义 View 或自定义 Drawable

标签: android animation


【解决方案1】:

如果我理解正确,您需要某种“操纵”——将一个元素的运动定义为另一个元素的函数。在您的情况下,此函数需要将线性位置转换为圆形位置。 不涉及动画 - 当用户移动蓝色圆圈时,红色圆圈也会相应移动。

您应该为蓝色圆圈运动注册回调(即 onTouchEvent 或 seekBar 的变化,具体取决于您如何实现“栏”)。然后你计算红色圆圈的新位置,然后把它放在那里。

这是一个自定义视图的简单工作示例,它根据给定的百分比值绘制两个圆。我使用简单的 SeekBar 进行了测试,它可以工作:

public class CanvasView extends View {
    private int centerX = 0;
    private int centerY = 0;
    private int radius = 0;
    private final int handleRadius = 25;

    private final Paint circlePaint = new Paint();
    private final Paint handlePaint = new Paint();
    private float percentValue = 0f;

    public CanvasView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public CanvasView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
    }

    public CanvasView(Context context) {
        super(context);
        init();
    }

    private void init() {
        circlePaint.setColor(Color.BLACK);
        handlePaint.setColor(Color.RED);
    }

    // Call this whenever the value of that linear bar is changed - so when the user moves his finger etc.
    public void setValue(float percentage) {
        this.percentValue = percentage;
        invalidate();
    }

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

        // this is the main circle
        canvas.drawCircle(centerX, centerY, radius, circlePaint);

        // calculate the angle based on the percentage of the linear movement (substracting (pi/2)     so the zero value is on top)
        double angle = (percentValue / 100) * (2 * Math.PI) - Math.PI / 2;

        // sin and cos to calculate the position of the smaller circle - the 'handle'
        float handleX = centerX + (float) (radius * Math.cos(angle));
        float handleY = centerY + (float) (radius * Math.sin(angle));

        // drawing the circle
        canvas.drawCircle(handleX, handleY, handleRadius, handlePaint);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // choose whatever values you want here, based on the view's size:
        centerX = w / 2;
        centerY = h / 2;
        radius = w / 3;
    }
}

【讨论】:

  • 问题是,如果我可以利用 sdk 中的一些动画代码,我就不必自己做所有的数学运算了。那里已经有用于旋转 abd 翻译的代码。如果没有更简单的解决方案弹出,我会接受这个
  • @Nilzor 您可以通过使用 RotateDrawable 来简化它,请参阅旋转 Drawable 的 setLevel 方法
  • 如果你不想自己做一些计算,你可以避免一些计算,但你不会得到更简单或更短的代码 - 这里的整个“数学”只有 3 短行。
  • 酷,这个解决方案与 rotateDrawable 配对将解决我的特定用例(这比我在问题中说明的示例要复杂一些)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多