Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 曲线动画的实现问题_Android_Android Animation - Fatal编程技术网

Android 曲线动画的实现问题

Android 曲线动画的实现问题,android,android-animation,Android,Android Animation,可能重复: 我想通过一个弯曲的路径移动一幅图像。在安卓系统中可能吗?我搜索了很多,但我只能找到有关缩放、旋转和平移动画的信息。所以任何人都有任何想法,请提供帮助。在android中可能吗?您可以逐帧制作动画。可以逐步定位对象以创建曲线。这将是有限的重用,但你可以做到 或者,您可以编写自己的动画来创建TweenAnimation的子类,该子类可以沿曲线设置动画。如果你擅长数学并且能够理解贝塞尔曲线,那么这可能是一个直截了当的选择。一旦你有了这个类,你可以很容易地在任何弯曲的路径上设置动画,但这需

可能重复:


我想通过一个弯曲的路径移动一幅图像。在安卓系统中可能吗?我搜索了很多,但我只能找到有关缩放、旋转和平移动画的信息。所以任何人都有任何想法,请提供帮助。在android中可能吗?

您可以逐帧制作动画。可以逐步定位对象以创建曲线。这将是有限的重用,但你可以做到

或者,您可以编写自己的动画来创建TweenAnimation的子类,该子类可以沿曲线设置动画。如果你擅长数学并且能够理解贝塞尔曲线,那么这可能是一个直截了当的选择。一旦你有了这个类,你可以很容易地在任何弯曲的路径上设置动画,但这需要更多的工作

下面是一些Java代码:


下面是功能齐全的代码,它将沿着由三个点定义的弯曲路径设置动画。点只是一个包含x值和y值的类(尽管您可以轻松地将其扩展到更多维度)

所有m变量都取自TranslateImation,并以类似的方式使用,因此如果有什么不合理的地方,您应该能够相对轻松地将其与TranslateImation代码进行比较

在initialize中对resolveSize的调用意味着您可以使用任何动画类型(绝对动画、相对动画、相对动画和父动画)指定圆弧的起点、终点和半径,就像对正常平移动画一样

calcBezier计算直接从中获取的二次bezier曲线。贝塞尔曲线应该允许平滑缩放,在图形中很常见(也用于Android的Path类)

实际的移动发生在applyTransformation中。interpolatedTime提供一个介于0和1之间的值,该值根据提供的插值器非线性增加。dx和dy是给定时间内沿曲线的实际x和y点

该类的唯一限制是y的最大变化总是发生在曲线的中心(请参见初始化中的中点计算)。但是,如果您想要非对称曲线,则可以很容易地修改,例如,沿曲线指定一个特定点,在该点处应出现高点

查看用于TranslateAnimation的android代码特别有帮助。见:

公共类ArcTranslate扩展动画{
私人点启动;
专用点端;
私家点中间;
私有最终浮动mFromXValue;
私人最终浮动mToXValue;
私人最终浮动价值;
私有最终int-mFromXType;
私有final int mToXType;
私有最终int-mYType;
/**
*沿三点和贝塞尔曲线定义的圆弧的平移
*
*@param duration-翻译完成所需的时间(毫秒)
*@param fromXType-Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF或Animation.RELATIVE_TO_PARENT中的一种。
*@param fromXValue-更改X坐标以在动画开始时应用
*@param toXType-Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF或Animation.RELATIVE_TO_PARENT中的一种。
*@param toXValue-将X坐标更改为在动画结束时应用
*@param yType-Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF或Animation.RELATIVE_TO_PARENT中的一种。
*@param yValue-更改Y坐标以应用于动画中间(圆弧半径)
*/
公共ArcTranslate(长持续时间,int-fromXType,float-fromXValue,
int-toXType,float-toXValue,int-yType,float-yValue){
设置持续时间(持续时间);
mFromXValue=fromXValue;
mToXValue=toXValue;
mYValue=yValue;
mFromXType=fromXType;
mToXType=toXType;
mYType=yType;
}
/**计算给定三个点的二次贝塞尔曲线上的位置
*以及时间流逝的百分比。
*从http://en.wikipedia.org/wiki/B%C3%A9zier_curve

*@param interpolatedTime-持续时间的分数,其中0您可以创建自己的类,如下所示:

public class BezierTranslateAnimation extends TranslateAnimation {

private int mFromXType    = ABSOLUTE;
private int mToXType      = ABSOLUTE;
private int mFromYType    = ABSOLUTE;
private int mToYType      = ABSOLUTE;
private float mFromXValue = 0.0f;
private float mToXValue   = 0.0f;
private float mFromYValue = 0.0f;
private float mToYValue   = 0.0f;
private float mFromXDelta;
private float mToXDelta;
private float mFromYDelta;
private float mToYDelta;
private float mBezierXDelta;
private float mBezierYDelta;

public BezierTranslateAnimation(float fromXDelta, float toXDelta,float fromYDelta, float toYDelta, float bezierXDelta, float bezierYDelta) {
     super(fromXDelta, toXDelta, fromYDelta, toYDelta);

      mFromXValue = fromXDelta;
      mToXValue   = toXDelta;
      mFromYValue = fromYDelta;
      mToYValue   = toYDelta;
      mFromXType  = ABSOLUTE;
      mToXType    = ABSOLUTE;
      mFromYType  = ABSOLUTE;
      mToYType    = ABSOLUTE;
      mBezierXDelta = bezierXDelta;
      mBezierYDelta = bezierYDelta;

}



@Override
protected void  applyTransformation(float interpolatedTime, Transformation t) {

    float dx=0,dy=0;

    if (mFromXValue != mToXValue) {

        dx  = (float) ((1.0-interpolatedTime)*(1.0-interpolatedTime)*mFromXValue + 2.0*interpolatedTime*(1.0-interpolatedTime)*mBezierXDelta + interpolatedTime*interpolatedTime*mToXValue);
    }

    if (mFromYValue != mToYValue) {

        dy  = (float) ((1.0-interpolatedTime)*(1.0-interpolatedTime)*mFromYValue + 2.0*interpolatedTime*(1.0-interpolatedTime)*mBezierYDelta + interpolatedTime*interpolatedTime*mToYValue);
    }

    t.getMatrix().setTranslate(dx, dy);

  }

}
然后将其与此签名一起使用:

BezierTranslateAnimation(float fromXDelta, float toXDelta,float fromYDelta, float toYDelta, float bezierXDelta, float bezierYDelta);

它的灵感来自Monkeyless的回答。 我创建了动画的一个子类,使用PathMeasure来计算平移。 您只需使用路径创建一个新的PathAnimation,并像使用任何其他动画一样使用它


谢谢。你有任何文章的示例或链接吗?你能告诉我如何创建自己的动画类作为tweenanimation的子类。你不使用动画的类型…我使用了Path.addArc()要创建弧,我希望我的视图可以继续移动,然后将此解决方案作为动画本身。很好!@vaiden,你能在这里发布示例吗?只需创建一个Path对象并将其提供给构造函数。实际上没有示例。我可以创建下面这样的路径来执行曲线动画吗?我将在哪里提供图像引用。我想移动I曲线动画中的mage//Init the Path.Path=new Path();//将路径的起始位置设置为(0,0).Path.moveTo(0,0);//向路径添加一条线,从(0,0)开始,在(100100)处结束。Path.addArc(0,0,0,0,0270);抱歉,我不能使用addArc()).我的应用程序名API为18@Monkeyless非常感谢您提供的代码。我使用此代码成功地为imageview设置了动画。但在设置imageview动画时,我在将onClickListener设置为imageview时遇到了问题。我发布了一个问题。请帮助。请参阅此答案:
BezierTranslateAnimation(float fromXDelta, float toXDelta,float fromYDelta, float toYDelta, float bezierXDelta, float bezierYDelta);
public class PathAnimation extends Animation {
private PathMeasure measure;
private float[] pos = new float[2];
public PathAnimation(Path path) {
    measure = new PathMeasure(path, false);
}

@Override
protected void applyTransformation(float interpolatedTime, Transformation t){
    measure.getPosTan(measure.getLength() * interpolatedTime, pos,null);
    t.getMatrix().setTranslate(pos[0], pos[1]);
}
}