Freeze screen orientation

纵饮孤独 提交于 2019-12-02 00:10:32

So, here is my solution.

private int getCurentOrientation() {
    Display d = ((WindowManager) getSystemService(WINDOW_SERVICE))
            .getDefaultDisplay();
    boolean isWide = d.getWidth() >= d.getHeight();
    switch (d.getRotation()) {
    case Surface.ROTATION_0:
        return isWide ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
                : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
    case Surface.ROTATION_90:
        return isWide ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
                : ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
    case Surface.ROTATION_180:
        return isWide ? ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
                : ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
    case Surface.ROTATION_270:
        return isWide ? ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
                : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
    }
    return -1;
}

private void lockOrientation(boolean lock) {
    if (lock) {
        setRequestedOrientation(getCurentOrientation());
    } else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
    }
}

On 4 devices (2 smartphones and 2 tablets) it works as nedded.

Create a memeber variable and save current set state. short is_landscape = -1;

oncheckedchange listener you can set your state permanently and save it.

if (is_landscape == -1) {
    Configuration config_screen = getResources().getConfiguration();
    int orientation = config_screen.orientation;
    if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
       setRequestedOrientation(Configuration.ORIENTATION_LANDSCAPE);
       is_landscape = 0;
    } else {
       setRequestedOrientation(Configuration.ORIENTATION_PORTRAIT);
       is_landscape = 1;
   }
}

Problem is that whenever you rotate your device then it recreates your activity so you loose your state. so just save your is_landscape variable on

@Override
protected void onSaveInstanceState(Bundle outState) {
    oustate.putExtra("last_state", is_landscape);
    super.onSaveInstanceState(outState);
}

you can restore your position on on restore instance

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    is_landscape = savedInstanceState.getShort("last_state");
    if (is_landscape == 0) {
        setRequestedOrientation(Configuration.ORIENTATION_LANDSCAPE);
    } else if (is_landscape == 1) {
        setRequestedOrientation(Configuration.ORIENTATION_PORTRAIT);
    }
    super.onRestoreInstanceState(savedInstanceState);
}

If you dont want to save and restore instance then you can use.

android:configChanges="orientation"

in your menifest file it will not allow to recreate activity on changing orientation of your device.

Hope it will work for you.

If you want to detect reverse state also the you can use

int state = (WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay().getRotation();

if state is Surface.ROTATION_0 then it will be portrait if state is Surface.ROTATION_90 then it will be landscape if state is Surface.ROTATION_180 then it will be reverse portrait if state is Surface.ROTATION_270 then it will be reverse landscape

set portrait in case of Surface.ROTATION_0 and Surface.ROTATION_180. set landscape in case of Surface.ROTATION_90 and Surface.ROTATION_270.

you can also set rotation instead of orientation so that your device will be in rotated state instead of oriented state.

Since you know how to get the current orientation, just write

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