Android中OrientationEventListener横竖屏宽高获取颠倒问题修复
问题修复方案
问题根源
GetScreenWidth/GetScreenHeight已经根据当前窗口的实际方向返回了正确的宽高值,你在横屏分支中手动交换宽高的操作属于画蛇添足,导致最终传入C++的参数颠倒。- 直接判断
orientation等于0/90/180/270这类精确值,会因为传感器角度波动导致回调触发不灵敏。
修复步骤
1. 修正OrientationEventListener逻辑
移除手动交换宽高的代码,改用范围判断横竖屏,并添加状态标记避免重复触发:
// 新增变量记录上次方向,避免重复执行逻辑 private var lastOrientation: String? = null mOrientationListener = object : OrientationEventListener(context, SensorManager.SENSOR_DELAY_UI) { override fun onOrientationChanged(orientation: Int) { // 忽略无效的方向值 if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) return // 用范围判断横竖屏,适配传感器角度波动 val isPortrait = orientation in 350..360 || orientation in 0..10 || orientation in 170..190 val isLandscape = orientation in 80..100 || orientation in 260..280 var currentOrientation: String? = null when { isPortrait -> currentOrientation = "Portrait" isLandscape -> currentOrientation = "LandScape" } // 仅当方向确定且发生变化时执行后续逻辑 if (currentOrientation != null && currentOrientation != lastOrientation) { lastOrientation = currentOrientation Log.d("orientation", "Orientation: $currentOrientation") // 直接获取当前方向下的正确宽高,无需手动交换 val width = TWOSScreenAspectsAndroid.GetScreenWidth() val height = TWOSScreenAspectsAndroid.GetScreenHeight() // 调用C++函数 OrientationChanged(pInstructionSetIndex, width, height) } } } if (mOrientationListener.canDetectOrientation()) { mOrientationListener.enable() }
2. 确保GetScreenWidth实现正确
补充GetScreenWidth的实现,与GetScreenHeight逻辑对应,保证返回当前方向下的实际宽度:
@JvmStatic public fun GetScreenWidth(): Int { val context: Context? = TWProcessStates.GetMainActivityContext() val activity = context as Activity return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { val metric = activity.windowManager.currentWindowMetrics val insets = metric.windowInsets.getInsetsIgnoringVisibility( WindowInsets.Type.navigationBars() or WindowInsets.Type.displayCutout() ) val insetsWidth = insets.left + insets.right metric.bounds.width() - insetsWidth } else { val displayMetrics = DisplayMetrics() activity.windowManager.defaultDisplay.getMetrics(displayMetrics) displayMetrics.widthPixels } }
说明
- 系统的
WindowMetrics(API30+)和DisplayMetrics(旧版本)都会根据当前窗口的方向返回适配后的宽高,无需手动交换。 - 范围判断横竖屏可以避免传感器角度波动导致的回调遗漏,提升触发稳定性。
lastOrientation标记可以减少同一方向下的重复回调,降低不必要的C++函数调用开销。
内容的提问来源于stack exchange,提问作者Jatin guglani
相关产品推荐
相关产品推荐

