Rotate CustomView without affecting the activity

别等时光非礼了梦想. 提交于 2019-12-11 06:13:00

问题


Hi I have a floating window in which my floating window serves as the video and it also have a controls inside the video which under the floating window

Now my question is it possible that I can rotate my custom view from floating window only without affecting the orientation of my activity

If someone already tried it please guide me towards it.

Thank you.


回答1:


I have never done it before. But I have an idea. You can use the below code to get the current orientation of the screen on your device.

OrientationEventListener onrientationEventListener = new OrientationEventListener(context, SensorManager.SENSOR_DELAY_UI) {
            @Override
            public void onOrientationChanged(int rotation) {
                Logger.e("Orientation: " + rotation);
            }
        };

And after that, depends on the value of "rotation", you can use rotate animation in Android to rotate your custom view.

@Beginer: Here is the code I implemented it. I used the above code in my custom view in my small camera app. It helps me to know which degree should I rotate the bitmap after taken. The toScreenOrientation() method bellow return a value in degrees (0, 90, 180, 270) you also modify it by yourself(whatever you want).

Using setOrientationChangedListener() method to help the parent(Activity, Fragment, etc.) receives a callback also.

public class TakePhotoView extends ConstraintLayout {

    private static final int SCREEN_ORIENTATION_0 = 0;
    private static final int SCREEN_ORIENTATION_90 = 90;
    private static final int SCREEN_ORIENTATION_180 = 180;
    private static final int SCREEN_ORIENTATION_270 = 270;

    private OnOrientationChangedListener mOnOrientationChangedListener;

    private OrientationEventListener mOrientationEventListener;

    private int mScreenRotation;

    public TakePhotoView(Context context) {
        this(context, null);
    }

    public TakePhotoView(Context context, AttributeSet attrs) {
        super(context, attrs);

        //....do something here

        mOrientationEventListener = new OrientationEventListener(context, SensorManager.SENSOR_DELAY_UI) {
            @Override
            public void onOrientationChanged(int rotation) {
                Logger.e("Orientation: " + rotation);

                if (rotation == OrientationEventListener.ORIENTATION_UNKNOWN) {
                    mScreenRotation = DEFAULT_SCREEN_ROTATION;
                    return;
                }

                mScreenRotation = rotation;

                if(mOnOrientationChangedListener != null){
                    mOnOrientationChangedListener.onOrientationChanged(rotation);
                }
            }
        };
    }

    private void takePhoto(Camera camera) {
        if (camera != null) {
            camera.takePicture(null, null, mPictureCallback);
        }
    }

    private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            final int screenRotation = mScreenRotation;

            int rotate = toScreenOrientation(screenRotation);

            // Rotate/Flip the bitmap depends on the 'rotate' value
        }
    };

    /**
     * Converts sensor rotation in degrees to screen orientation constants.
     *
     * @param rotation sensor rotation angle in degrees
     * @return Screen orientation angle in degrees (0, 90, 180, 270).
     */
    private int toScreenOrientation(int rotation) {
        if (rotation > 290 || rotation <= 70) {
            return SCREEN_ORIENTATION_0;
        } else if (rotation > 70 && rotation <= 110) {
            return SCREEN_ORIENTATION_90;
        } else if (rotation > 110 && rotation <= 250) {
            return SCREEN_ORIENTATION_180;
        } else {
            return SCREEN_ORIENTATION_270;
        }
    }

    public void setOrientationChangedListener(OnOrientationChangedListener orientationChangedListener){
        this.mOnOrientationChangedListener = orientationChangedListener;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // Interfaces
    ////////////////////////////////////////////////////////////////////////////////////////////////

    public interface OnOrientationChangedListener {
        void onOrientationChanged(int rotation);
    }
}

Can I use this listener even I disable rotation in my manifest? -> It still works fine.

Hope it helps.




回答2:


Looks like you do not want your Activity to be recreated on device rotation. If so, then add configChanges attribute in AndroidManifest:

<activity
      ...
      android:configChanges="orientation" >

This will stop activity recreation on rotation. But in your activity you can check that device has been rotated in onConfigurationChanged() method:

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);

  // Checks the orientation of the screen
  if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
    ...
  } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
    ...
  }
}

Do not forget to read android developer guides. ;)




回答3:


I have found a way to do this but I used alertDailog. The logic will be the same for all views.

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

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    AlertDialog.Builder alert123 = new AlertDialog.Builder(StackOverflow2.this);
    View current_view = getLayoutInflater().inflate(R.layout.password_alert,null);
    l2 = current_view.findViewById(R.id.linearView);
    // Here l2 is linear layout getting root layout of password_alert

    alert123.setView(current_view);
    dialog = alert123.create();
    dialog.show();

    OrientationEventListener onrientationEventListener = new OrientationEventListener(getBaseContext(), SensorManager.SENSOR_DELAY_UI) {
        @Override
        public void onOrientationChanged(int rotation) {
            Log.e("Orientation: " , String.valueOf(rotation));

            if(rotation==270 || rotation==90)
            {
                if(rotation==270)
                {
                    l2.setRotation(90);
                }
                else
                {
                    l2.setRotation(270);
                }
                dialog.getWindow().setLayout(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
                Toast.makeText(StackOverflow2.this, "Change Dialog Rotation", Toast.LENGTH_SHORT).show();
            }
            else
            {
                if(rotation==180)
                {
                    l2.setRotation(180);
                }
                else
                {
                    l2.setRotation(0);
                }

                Toast.makeText(StackOverflow2.this, "Normal Display to Occur", Toast.LENGTH_SHORT).show();
            }


        }
    };
    if (onrientationEventListener.canDetectOrientation()) {
        Log.v("ORIE", "Can detect orientation");
        onrientationEventListener.enable();
    } else {
        Log.v("ORIE", "Cannot detect orientation");
        onrientationEventListener.disable();
    }

}

Here are some pictures : 0 Degree

90 Degree

270 Degree

As you can see the background activity is in potrait mode always. The alert dialog's height and width is a little off but you can change your view's dimensions differently. I hope this code solves your problem.



来源:https://stackoverflow.com/questions/46417417/rotate-customview-without-affecting-the-activity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!