如何像youtube在android上那样处理视图旋转



我想实现youtube处理其视频定向的方式。

在说我必须使用onConfigurationChanged之前,有几件事需要记住。


需要考虑的事项

  1. 手机方向。这意味着你拿手机的方式。它可以是PORTRAIT或LANSCAPE

  2. 屏幕方向。这意味着视图的显示方式。无论手机的方向如何,它都可能是PORTRAIT或LANDSCAPE


青少年旋转是如何工作的

  1. 如果手机处于PORTRAIT模式(使用操作系统快速设置(
  • 屏幕将保持在PORTRAIT中。如果你转动手机也没关系
  • 旋转屏幕的唯一方法是按下旋转按钮
  • 屏幕将保持上次选择的方向,即使旋转手机也不会改变。PORTRAIT将保留为PORTRAIT,景观将保留为景观
  1. 如果手机处于自动旋转模式
  • 如果你旋转手机,屏幕就会随之旋转。我的意思是,如果手机在PORTRAIT,屏幕就会是PORTRAIT。景观也是如此。

  • 如果按下旋转按钮,无论手机方向如何,屏幕方向都会发生变化。在这种情况下,监听传感器方向的唯一方法是将手机旋转到屏幕旋转的同一侧,然后返回。这是为了让手机传感器再次控制方向。


我有什么

使用onConfigurationChanged,我可以知道何时旋转手机(如果启用了AUTO-rotate(并定义布局:

override fun onConfigurationChanged(newConfig: Configuration) {
when (newConfig.orientation) {
Configuration.ORIENTATION_PORTRAIT -> buildPortrait()
Configuration.ORIENTATION_LANDSCAPE -> buildLandscape()
}
super.onConfigurationChanged(newConfig)
}

使用旋转按钮,我可以处理屏幕方向(当手机处于操作系统的PORTRAIT BLOCKED时(

fun rotate() {
val orientation = requireActivity().requestedOrientation
val isRotationOn = Settings.System.getInt(requireActivity().contentResolver,
Settings.System.ACCELEROMETER_ROTATION, 0) == 1
requireActivity().requestedOrientation = if (isRotationOn) {
// AUTO-ROTATE enabled
TODO()
} else 
// PORTRAIT BLOCKED
if (orientation == PORTRAIT) {
buildLandscape()
LANDSCAPE
} else {
buildPortrait()
PORTRAIT
}
}

我不能实现什么当我启用了AUTO-ROTATE来处理传感器的旋转时,我不知道如何处理屏幕旋转,同时,有一个旋转按钮可以进行旋转,而不考虑AUTO-ROTATE。


重要信息:我在任何地方都找不到任何解决方案的示例。

您需要使用OrientationEventListener来侦听方向更改,并在方向更改时将requestedOrientation设置回ActivityInfo.SCREEN_ORIENTATION_USERonOrientationChanged中传递的方向值从0到359,-1表示平坦。您需要根据以下代码将其映射到4个方向。

orientationEventListener = object: OrientationEventListener(this) {
override fun onOrientationChanged(orientation: Int) {
val newOrientation = when (orientation) {
in 0 .. 44 -> 0
in 45 .. 134 -> 1
in 135 .. 224 -> 2
in 225 .. 314 -> 3
in 315 .. 359 -> 0
else -> ORIENTATION_UNKNOWN
}
if (newOrientation != previousOrientation) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER
}
previousOrientation = newOrientation
}
}

记住,只有当上有自动旋转设置时,才启用上述侦听器

val autoRotationOn = Settings.System.getInt(contentResolver,
Settings.System.ACCELEROMETER_ROTATION, 0) == 1
if (autoRotationOn) {
orientationEventListener.enable()
} else {
orientationEventListener.disable()
}

由于自动旋转设置可能在当前活动的生命周期内更改,因此您必须听取值更改并启用/禁用orientationEventListener

private val contentObserver = object:ContentObserver(handler) {
override fun onChange(selfChange: Boolean) {
super.onChange(selfChange)
setupOrientationEventListener()
}
}

val settingUri = Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION)
contentResolver.registerContentObserver(settingUri, false, contentObserver)

最新更新