Freeze screen orientation

≯℡__Kan透↙ 提交于 2019-12-20 03:21:13

问题


There is CheckBox with following code:

    CheckBox cb = (CheckBox)findViewById(R.id.freezer);
    cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
            } else {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
            }
        }
    });

So, when i check it, screen is rotated to default system orientation (landscape for my tablet).

I need to freeze CURRENT orientation. If you turned device to portrait and toggled CheckBox, device rotation must be ingored until CheckBox is unchecked.

Display.getRotation() is not a solution, because each device has it's own Surface.ROTATION


回答1:


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.




回答2:


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.




回答3:


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

if(isChecked){
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}


来源:https://stackoverflow.com/questions/10309588/freeze-screen-orientation

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