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

Android 11+强制旋转屏幕后WindowInsets获取Insets左右值为0问题求解

问题根因

你遇到的insets值获取不准确问题,本质是调用getCurrentWindowMetrics的时机早于系统布局更新完成时间:强制旋转触发后,Activity的布局、WindowInsets计算需要一定时间,你在旋转代码执行后立刻读取的WindowMetrics还是旋转前的缓存值,所以左右边距不对。
你观测到的几个异常现象也符合这个逻辑:应用第二次启动时系统保留了上一次的Insets缓存,所以能拿到正确值;触碰主屏幕会清掉系统保存的应用Window状态缓存,重启后首次读取就会拿到旧值。


解决方案

方案1:监听WindowInsets回调(最可靠)

不要在Activity早期生命周期(onCreate/onStart)主动拉取Insets,而是给根布局注册OnApplyWindowInsetsListener,系统完成Insets计算后会主动回调,此时拿到的边距一定是当前最新值:

// 在Activity onCreate中调用
getWindow().getDecorView().setOnApplyWindowInsetsListener((v, windowInsets) -> {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        Insets insets = windowInsets.getInsetsIgnoringVisibility(
            WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout()
        );
        // 此处获取的left、right为准确值,可直接保存使用
        int leftInset = insets.left;
        int rightInset = insets.right;
        int usableWidth = v.getWidth() - leftInset - rightInset;
        int usableHeight = v.getHeight() - insets.top - insets.bottom;
    }
    return windowInsets; // 如果子布局需要用到Insets,不要消费,直接返回原对象
});

方案2:延迟到布局完成后主动获取

如果业务需要主动调用方法获取尺寸,把获取逻辑post到主线程消息队列末尾,等布局渲染完成后再执行:

// 执行强制横屏代码后
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// 等待布局完成后再读取尺寸
getWindow().getDecorView().post(() -> {
    int currentWidth = getDisplaySize(getWindowManager(), true);
    // 此处拿到的是正确的宽高值
});

方案3:使用Jetpack WindowManager兼容库(推荐)

Google官方推出的WindowManager兼容库已经处理了不同版本、不同场景下的Insets获取逻辑,不需要自己做版本判断,稳定性更高:

  1. 先添加依赖:
    // 模块级build.gradle中添加
    implementation "androidx.window:window:1.2.0"
    
  2. 直接获取最新的WindowMetrics:
    WindowMetricsCalculator calculator = WindowMetricsCalculator.getOrCreate();
    WindowMetrics currentMetrics = calculator.computeCurrentWindowMetrics(this);
    WindowInsetsCompat insetsCompat = WindowInsetsCompat.toWindowInsetsCompat(
        currentMetrics.getWindowInsets()
    );
    // 获取边距
    Insets insets = insetsCompat.getInsets(
        WindowInsetsCompat.Type.navigationBars() | WindowInsetsCompat.Type.displayCutout()
    );
    int leftInset = insets.left;
    int rightInset = insets.right;
    // 计算可用尺寸
    Rect bounds = currentMetrics.getBounds();
    int usableWidth = bounds.width() - leftInset - rightInset;
    int usableHeight = bounds.height() - insets.top - insets.bottom;
    

内容的提问来源于stack exchange,提问作者CodingBruceLee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 12:15:03