0
votes

I want to create icon orientation like default camera. When you rotate device, icons rotate relevantly. But sometimes, it rotates 270 degree, icons in default camera only rotate 0 - 180 degree. This is my source codes.

**RotationActivity **

public class RotationActivity extends Activity {

    public static final String TAG = "RotationActivity";

    private ImageView btnTest;


    OrientationEventListener orientationEventListener;
    private int current_orientation = 0;
    private int old_ui_rotation = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.rotation_activity);

        btnTest = (ImageView) findViewById(R.id.imvImage);

        orientationEventListener = new  OrientationEventListener(RotationActivity.this) {

            @Override
            public void onOrientationChanged(int orientation) {

                orientationChanged(orientation);
            }
        };
    }

    private void orientationChanged(int orientation) {

        if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) {
            return;
        }
        int diff = Math.abs(orientation - current_orientation);
        if (diff > 180) {
            diff = 360 - diff;
        }
        // only change orientation when sufficiently changed
        if (diff > 60) {
            orientation = (orientation + 45) / 90 * 90;
            orientation = orientation % 360;
            if (orientation != current_orientation) {
                this.current_orientation = orientation;
                Log.d(TAG, "current_orientation is now: " + current_orientation);
                changeUI();
            }
        }
    }


    @Override
    protected void onStart() {
        super.onStart();
        orientationEventListener.enable();
    }

    @Override
    protected void onStop() {
        super.onStop();
        orientationEventListener.disable();
    }

    private static final float PIVOT_VALUE = 0.5f;
    private static final long DEFAULT_ROTATE_DURATION_MS = 500;

    private void changeUI() {
        int rotation = this.getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation)

        {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int relative_orientation = (current_orientation + degrees) % 360;
        Log.d(TAG, "    current_orientation = " + current_orientation);
        Log.d(TAG, "    degrees = " + degrees);
        Log.d(TAG, "    relative_orientation = " + relative_orientation);
        final int ui_rotation = (360 - relative_orientation) % 360;
        Log.d(TAG, "    ui_rotation = " + ui_rotation);

        RotateAnimation rotateAnimation = new RotateAnimation(old_ui_rotation,
                ui_rotation,
                RotateAnimation.RELATIVE_TO_SELF, PIVOT_VALUE,
                RotateAnimation.RELATIVE_TO_SELF, PIVOT_VALUE);
        rotateAnimation.setDuration(DEFAULT_ROTATE_DURATION_MS);
        rotateAnimation.setFillAfter(true);

        btnTest.startAnimation(rotateAnimation);

        old_ui_rotation = ui_rotation;
    }

}

rotation_activity.xml

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

    <ImageView
        android:id="@+id/imvImage"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@mipmap/ic_launcher" />


</LinearLayout>

Thanks a lot.

2

2 Answers

1
votes
int diff = Math.abs(orientation - current_orientation);

I think the problem is that you ignore the sign that indicates the direction of the rotation. You should use the sign to determine whether to rotate 90° or -90°.

1
votes

I think the problem is from here:

final int ui_rotation = (360 - relative_orientation) % 360;

ui_rotation will never be 360. If you rotate your device from 270(old_ui_rotation) to 360, instead of rotate the icon for 90, it will rotate for 270. May be you can add this:

if((old_ui_rotation==270)&&(ui_rotation==0)) old_ui_rotation = -90;