在安卓系统中,如何使用ObjectAnimator沿曲线移动到x点?

5 人关注

我有一个图像视图 "石头",正在将它从当前位置移动到一个X,Y的位置。我想让它沿着一条曲线移动。请告诉我如何做到这一点(我已将最小api设置为11)。

ObjectAnimator moveX = ObjectAnimator.ofFloat(stone, "x", catPos[0] );
ObjectAnimator moveY = ObjectAnimator.ofFloat(stone, "y", catPos[1] );
AnimatorSet as = new AnimatorSet();
as.playTogether(moveX, moveY);
as.start();
    
1 个评论
使用PathMeasure,它将让你在任何你想要的路径上移动。
android
Aparna
Aparna
发布于 2015-03-06
6 个回答
Dileep P G
Dileep P G
发布于 2021-07-22
已采纳
0 人赞同

在我看来,布迪乌斯的答案是完全有用的。

下面是我使用的动画师对象。

目的:沿着Path "路径 "移动View "视图"。

安卓v21+。

// Animates view changing x, y along path co-ordinates
ValueAnimator pathAnimator = ObjectAnimator.ofFloat(view, "x", "y", path)

Android v11+。

// Animates a float value from 0 to 1 
ValueAnimator pathAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
// This listener onAnimationUpdate will be called during every step in the animation
// Gets called every millisecond in my observation  
pathAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
float[] point = new float[2];
@Override
    public void onAnimationUpdate(ValueAnimator animation) {
        // Gets the animated float fraction
        float val = animation.getAnimatedFraction();
        // Gets the point at the fractional path length  
        PathMeasure pathMeasure = new PathMeasure(path, true);
        pathMeasure.getPosTan(pathMeasure.getLength() * val, point, null);
        // Sets view location to the above point
        view.setX(point[0]);
        view.setY(point[1]);

类似于。安卓系统,沿着一个路径移动位图?

这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下面留下评论--你可以随时对自己的帖子发表评论,一旦你有足够的 声誉 你将能够 评论任何帖子 .
谢谢你的反馈。我已经从我的解决方案中添加了工作代码,使其成为一个完整的答案。希望这对你有帮助!
这几乎是可行的,但似乎当动画完成时,值最终会被重置(ValueAnimator的例子)。
你在这里犯了两个错误。首先,正如@MattFoley所提到的,ValueAnimator在动画结束时重置数值,所以你需要将 false 而不是 true 传入 PathMeasure 的构造函数。其次,你需要通过调用 setX() setY() 方法来平移视图而不是改变其位置。使用 setTranslationX() setTranslationY() 方法。事实上,你下面有正确的答案,由@Budius写的。
Budius
Budius
发布于 2021-07-22
0 人赞同

你有两个选择。

都需要一个 Path 对象来定义你的曲线。

Path path = new Path();
path. // define your curve here

如果只使用Lollipop(API 21),则使用ObjectAnimator.ofFloat(...path) like this:

ObjectAnimator.ofFloat(stone, View.X, View.Y, path).start();

如果这不是一个选项,你可以使用AnimatorListener来接收每个动画帧的更新,并使用PathMeasure来获得该点上的值,像这样。

PathMeasure pm;
float point[] = {0f, 0f};
private final ValueAnimator.AnimatorUpdateListener listener = 
       new ValueAnimator.AnimatorUpdateListener(){
   @Override
   public void onAnimationUpdate (ValueAnimator animation) {
        float val = animation.getAnimatedFraction();
        pm.getPosTan(pm.getLength() * val, point, null);
        stone.setTranslationX(point[0]);
        stone.setTranslationY(point[1]);
// and then to animate
pm = new PathMeasure(path, false);
ValueAnimator a = ValueAnimator.ofFloat(0.0f 1.0f);
a.setDuration(/* your duration */);
a.setInterpolator(/* your interpolator */);
a.addUpdateListener(listener);
a.start();
    
A Honey Bustard
A Honey Bustard
发布于 2021-07-22
0 人赞同

玩弄插值器。例如,为x和y设置两个不同的插值器。

moveX.setInterpolator(new AccelerateDecelerateInterpolator());
moveY.setInterpolator(new DecelerateInterpolator());

还有更多(LinearInterpolator, AccelerateInterpolator...),但我认为这应该是你想要的组合。

ingenious, so much clever
Aparna
Aparna
发布于 2021-07-22
0 人赞同

谢谢你的回答,但我找到了自己的答案。只是在Objectanimator语句中添加了一些额外的x,y位置。它在走到最后一个位置之前走到了这些位置,并追踪了一条路径!这就是我的答案。

ObjectAnimator moveX = ObjectAnimator.ofFloat(stone, "x", catPos[0]-20,catPos[0]-10,catPos[0] );
ObjectAnimator moveY = ObjectAnimator.ofFloat(stone, "y",catPos[1]-20,catPos[1]-10, catPos[1] );
    
当我试图通过曲线移动一个ImageView时,我得到了一个NPE。 path = new Path(); path.moveTo((float)(maxX/2)+(maxX/4),maxY/4); path.quadTo((float)(maxX/2)+(maxX/4),maxY/4, (float)(maxX/2)+(maxX/4)+30, maxY/2); ObjectAnimator animator = new ObjectAnimator(); animator.ofFloat(img,View.X,View.Y,path); animator.setDuration(1000); animator.setStartDelay(600); animator.start(); 异常是: java.lang.NullPointerException:试图获取空数组的长度
Markers
Markers
发布于 2021-07-22
0 人赞同

The Path class has methods for creating non-straight lines of several types; arcs, circles, ovals, rectangles, cubic & quadratic bezier curves, which you can then animate your object along.

正如Budius所指出的,你确实需要为API 21(Lollipop)或更高版本编码,以使用对象翻译的路径。 它现在已经超过两年了。

另一方面,在 "野外 "使用路径的情况下,除了非常简单的例子之外,似乎还缺少其他东西,所以也许它们还没有流行起来是有原因的。

Qing
Qing
发布于 2021-07-22
0 人赞同

查看这个链接,了解3种平行地对 View 的几个属性进行动画的方法。 https://developer.android.com/guide/topics/graphics/prop-animation#view-prop-animator

The 1st 的方式是使用AnimatorSet。

Below is the 2nd 办法。

public static ObjectAnimator ofPropertyValuesHolder (Object target, 
            PropertyValuesHolder... values)

API文档对ObjectAnimator的这个构造函数描述如下。

"当用同一个ObjectAnimator同时给几个属性做动画时,应该使用这个变体,因为PropertyValuesHolder允许你把一组动画值与一个属性名称联系起来。"

Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder transX = PropertyValuesHolder.ofKeyframe("translationX", kf0, kf1, kf2);
PropertyValuesHolder transY = PropertyValuesHolder.ofKeyframe("translationY", kf0, kf1, kf2);
ObjectAnimator transAnim = ObjectAnimator.ofPropertyValuesHolder(view2animate, transX, transY);