setRequestedOrientation,但仍然根据传感器而改变

我想在处理屏幕方向上模拟YouTubevideo查看行为。

用例:
p1 。 当用户按最大化 – >活动总是进入风景
p2 。 当用户按最小化 – >活动总是进入纵向
p3 。 当用户旋转设备 – >屏幕方向应该相应地改变,即使之前应用p1p2

目前我使用:

@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); } 

但是这会永久锁定方向,并且会失败。

玩了一段时间后,我find了正确的解决方案。 首先 – 问题是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(); 

@尤里的答案对我很好,在这里它是在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) { 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 }