You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中OrientationEventListener横竖屏宽高获取颠倒问题修复

问题修复方案

问题根源

  1. GetScreenWidth/GetScreenHeight已经根据当前窗口的实际方向返回了正确的宽高值,你在横屏分支中手动交换宽高的操作属于画蛇添足,导致最终传入C++的参数颠倒。
  2. 直接判断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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 04:45:36