Spin the image center instead of wide circle in android

Viewed 46

I have an ImageView and Button. Button view positioned at bottom of the screen. ImageView positioned above of the button. When i click the button, image should move to center of the screen. After moving to center, click on image should spin. But in my case it spin in wider circle instead of the spin at center.

I am using below code.

            <ImageView
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:scaleType="centerCrop"
            android:visibility="visible" />

            <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:text="Start" />

after click on button, moving to center of the screen

image.animate().y(metrics.heightPixels / 2 - image.getHeight() / 2).x(metrics.widthPixels / 2 - image.getWidth() / 2)

Rotating the image after above step.

                RotateAnimation animRotate = new RotateAnimation(0.0f, 360.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            animRotate.setDuration(duration);
            animRotate.setInterpolator(new DecelerateInterpolator(1.5f));
image.startAnimation(animRotate)

Instead of spinning at the center, it spin like wider circle. Can you help.

1 Answers

The translation of the view occurs post-layout. The result is that, although the view appears in a new location (the post-translation location), the view is still considered by the rotation animation to be in its original location (its layout position). You are seeing the view rotate in a wide circle because the center of rotation is the pre-translation center of the view. Why this is is an enduring mystery to me.

To get around this, you will need to compute the true center of the view as it appears on the screen. The following code shows how this can be done. The view is translated from the center of the screen to the top-left corner and rotated in place. (You don't have to use the global layout listener.)

// Wait until everything is laid out before we can manipulate it.
image.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    int duration = 1000;
    @Override
    public void onGlobalLayout() {
        image.getViewTreeObserver().removeOnGlobalLayoutListener(this);

        // Save the initial location of the top-left corner of the view.
        float initX = image.getX();
        float initY = image.getY();
        image.animate().y(0).x(0).setDuration(duration).withEndAction(new Runnable() {
            @Override
            public void run() {
                // The post-translation center of the view is at the new top-left corner
                // plus 1/2 the width and height of the view. We need to compute the 
                // displacement from the original center to feed into the RotationAnimation.
                RotateAnimation animRotate =
                        new RotateAnimation(0.0f, 360.0f,
                                Animation.ABSOLUTE, image.getX() - initX + (image.getWidth() / 2f),
                                Animation.ABSOLUTE, image.getY() - initY + (image.getHeight() / 2f));
                animRotate.setDuration(duration);
                image.startAnimation(animRotate);
            }
        });

    }
});

enter image description here

Related