在安卓中将图像沿着圆形路径移动

10

我有一张图片,希望在按钮的onClick()事件中以圆形路径移动它,不需要动画。

我不知道该怎么做... 有什么帮助吗?


这是我的主类

public class MainActivity extends Activity {
MyAnimation animation;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    animation =new MyAnimation ();

}

我正在使用你提供的代码,代码如下:

public class MyAnimation extends Animation {
float cx,cy,prevX,prevY,r;

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

    float angle = (float) (interpolatedTime * 2 * Math.PI);
    // r = radius, cx and cy = center point, a = angle (radians)
    float x = (float) (cx + r * Math.cos(angle)) ; 
    float y = (float) (cy + r * Math.sin(angle));

    float dx = prevX - x;
    float dy = prevY - y;

    prevX = x;
    prevY = y;

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

这是我想让其以圆形运动的图像的 XML。

<ImageView
    android:id="@+id/myanimation"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:src="@drawable/ic_launcher" />

如果您想手动旋转视图- http://stackoverflow.com/a/34898135/4440874 - Jyotman Singh
1个回答

29
我认为你有两个选择:要么创建自定义动画,要么创建ImageView,然后使用Surface沿着路径自己绘制它。第一个选项更容易,而且可能会给出更好的结果,因为在Animation类中,时间处理由Interpolators(线性时间、快速开始、正常结束等)处理。我强烈建议你编写自定义动画,因为我不明白为什么你不想使用Animation类(动画图像正是你想要的)。编辑:我花了一些时间实现了以下内容。它不是完美的,但可以在圆形路径中动画显示图像。
活动:
public class MainActivity extends Activity {

    private ImageView image;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        image = (ImageView) findViewById(R.id.image);

        image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Animation anim = new MyAnimation(image, 100);
                anim.setDuration(3000);
                image.startAnimation(anim);
            }
        });
    }

}

动画类:

public class MyAnimation extends Animation {

    private View view;
    private float cx, cy;           // center x,y position of circular path
    private float prevX, prevY;     // previous x,y position of image during animation
    private float r;                // radius of circle
    private float prevDx, prevDy;


    /**
     * @param view - View that will be animated
     * @param r - radius of circular path
     */
    public MyAnimation(View view, float r){
        this.view = view;
        this.r = r;
    }

    @Override
    public boolean willChangeBounds() {
        return true;
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        // calculate position of image center
        int cxImage = width / 2;
        int cyImage = height / 2;
        cx = view.getLeft() + cxImage;
        cy = view.getTop() + cyImage;

        // set previous position to center
        prevX = cx;
        prevY = cy;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        if(interpolatedTime == 0){
            t.getMatrix().setTranslate(prevDx, prevDy);
            return;
        }

        float angleDeg = (interpolatedTime * 360f + 90) % 360;
        float angleRad = (float) Math.toRadians(angleDeg);

        // r = radius, cx and cy = center point, a = angle (radians)
        float x = (float) (cx + r * Math.cos(angleRad));
        float y = (float) (cy + r * Math.sin(angleRad));


        float dx = prevX - x;
        float dy = prevY - y;

        prevX = x;
        prevY = y;

        prevDx = dx;
        prevDy = dy;


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

XML布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:src="@drawable/ic_launcher" />

</RelativeLayout>

您可能需要在此处进行微调,以确切地获得所需的内容,但这可以作为基础。

它没有动...我觉得我在调用MyAnimation类的代码中犯了一些错误。你能上传完整的代码吗?提前感谢 - Rohit
不,我不能。但我可以尝试帮助您解决问题。您能展示一下MyAnimation类的确切代码以及您如何使用它吗? - Jeffrey Klardie
@BlueGreen:你解决了吗?完成一次旋转后,它会回到圆心然后重新开始。 - seema
1
脑海中首先浮现的是第一个if语句:if(interpolatedTime == 0),它会返回。删除它可能会有所帮助。否则,您可能需要调整fillBeforefillAfter值(不要忘记fillEnabled)。 - Jeffrey Klardie
很遗憾,我现在没有时间进行调查。您应该调试应用程序以查看发生了什么(initialize是否被多次调用?也许它应该调用其父级)。我还会在applyTransformation()调用中添加日志,并打印插值时间(它应该从0到100,每次重复一次)。您删除了if()检查吗?如果这不起作用,您可以在ImageView的onDraw()中设置断点并检查是谁调用它(某些内容正在重绘图像在重复之间)。 - Jeffrey Klardie
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接