Home » Android » Move an Image in circular path in android

Move an Image in circular path in android

Posted by: admin May 14, 2020 Leave a comment

Questions:

I am having an Image, I wanted to move it in circular path onClick() event of button without animation,

I don’t know how to do it.. Any help??


This is my main class

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

}

and I am using code given by you as

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

}

And this is my xml of image which i wanted to move in circular shape.

<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" />
How to&Answers:

I think you have two options here: either you create a custom animation, or you create your ImageView and then use a surface to draw it along the path yourself.

The first option is much easier, and will probably give better results given that in the Animation class the timing is handled for you with Interpolators (Linear time, start fast, end normal, etc). I strongly advice you to write the custom animation, as I don’t see why you would not want to use the Animation class (animating an image is exactly what you want).

Edit: I took some time and implemented the following. It’s not spotless, but does animate the image in a circular path.

Activity:

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

}

Animation class:

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 Layout:

<?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>

You probably need to tweak it here and there to get what you want exactly, but this can be a basis for that.