setRequestedOrientation,但仍然根据传感器

时间:2017-10-26 11:55:37

标签: android android-activity orientation android-sensors

我想在处理屏幕方向时模拟youtube视频观看行为。

用例:
P1 即可。当用户按最大化时 - >活动总是进入景观中 的 P2 即可。当用户按最小化时 - >活动总是进入肖像 的 P3 即可。当用户旋转设备时 - >即使之前应用 p1 p2 ,屏幕方向也应相应更改。

目前我使用:

 @Override
 public void onClick(View view) {
     if (getResources().getConfiguration().orientation == ORIENTATION_PORTRAIT) {
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
     } else {
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
     }

然而,这会永久锁定方向并且 p3 失败。

2 个答案:

答案 0 :(得分:4)

玩了一会儿之后我找到了合适的解决方案。 首先 - 问题是android在setRequestedOrientation调用后锁定屏幕,你不能混合使用两者,唯一要做的就是手动完成所有事情。

以下是:

class PlayerOrientationListener extends OrientationEventListener {
    PlayerOrientationListener() {
        super(VideoPlayerActivity.this);
    }

    @Override
    public void onOrientationChanged(int orientation) {
        int threshold = 5;
        if (Math.abs(orientation - 0) < threshold) orientation = 0;
        else if (Math.abs(orientation - 90) < threshold) orientation = 90;
        else if (Math.abs(orientation - 180) < threshold) orientation = 180;
        else if (Math.abs(orientation - 270) < threshold) orientation = 270;

        switch (orientation) {
            case 0:
                if (!orientationLandscapeLocked) {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                    orientationPortraitLocked = false;
                }
                break;
            case 90:
                if (!orientationPortraitLocked) {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
                    orientationLandscapeLocked = false;
                }
                break;
            case 180:
                if (!orientationLandscapeLocked) {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
                    orientationPortraitLocked = false;
                }
                break;
            case 270:
                if (!orientationPortraitLocked) {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                    orientationLandscapeLocked = false;
                }
                break;
        }
    }
}

和活动代码:

View.OnClickListener onExpandClick = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (getResources().getConfiguration().orientation == ORIENTATION_PORTRAIT) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
                orientationLandscapeLocked = true;
                orientationPortraitLocked = false;
            } else {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
                orientationPortraitLocked = true;
                orientationLandscapeLocked = false;
            }
        }
    };
btnExpandVideo.setOnClickListener(onExpandClick);

orientationListener = new PlayerOrientationListener();
orientationListener.enable();

答案 1 :(得分:3)

@ Yuriy的答案对我来说非常有用,这里是在Kotlin进行一些小修改,以便它可以存在于一个单独的文件中:

class PlayerOrientationListener(val activity: Activity?) : OrientationEventListener(activity) {
    companion object {
        private const val ROT_THRESHOLD = 5

        private const val ROT_0 = 0
        private const val ROT_90 = 90
        private const val ROT_180 = 180
        private const val ROT_270 = 270
    }

    private var orientationLockedPortrait = false
    private var orientationLockedLandscape = false

    fun lockLandscape() {
        activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
        orientationLockedLandscape = true
        orientationLockedPortrait = false
    }

    fun lockPortrait() {
        activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
        orientationLockedPortrait = true
        orientationLockedLandscape = false
    }

    override fun onOrientationChanged(orientation: Int) {
        if (orientation == ORIENTATION_UNKNOWN) {
            return
        }

        val rotation: Int =
                when {
                    Math.abs(orientation - ROT_0) < ROT_THRESHOLD -> ROT_0
                    Math.abs(orientation - ROT_90) < ROT_THRESHOLD -> ROT_90
                    Math.abs(orientation - ROT_180) < ROT_THRESHOLD -> ROT_180
                    Math.abs(orientation - ROT_270) < ROT_THRESHOLD -> ROT_270
                    else -> ORIENTATION_UNKNOWN
                }

        when (rotation) {
            ROT_0 -> if (!orientationLockedLandscape) {
                activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
                orientationLockedPortrait = false
            }
            ROT_90 -> if (!orientationLockedPortrait) {
                activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
                orientationLockedLandscape = false
            }
            ROT_180 -> if (!orientationLockedLandscape) {
                activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
                orientationLockedPortrait = false
            }
            ROT_270 -> if (!orientationLockedPortrait) {
                activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
                orientationLockedLandscape = false
            }
        }
    }
}

然后在你的片段中,例如:

val orientationListener = PlayerOrientationListener(activity)
orientationListener.enable()

menuItemMaximize?.setOnMenuItemClickListener {
    orientationListener.lockLandscape()
    true
}

menuItemMinimize?.setOnMenuItemClickListener {
    orientationListener.lockPortrait()
    true
}