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]);
}
}