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

Android获取应用窗口尺寸:适配分屏、弹窗视图等场景

全场景应用窗口净尺寸计算(Java实现)

要搞定普通全屏、分屏、三星弹窗这些场景下的窗口净尺寸(不含状态栏、导航栏),核心是抓准系统UI的占用区域,同时适配不同Android版本的API,下面是具体实现:

1. 优先用API 30+的WindowInsets(适配绝大多数新设备)

从Android 11开始,官方的WindowInsets API能直接拿到系统UI的Insets,而且自动适配各种多窗口模式,不用额外处理:

// 在Activity中实现
View rootView = getWindow().getDecorView().getRootView();
rootView.setOnApplyWindowInsetsListener((view, windowInsets) -> {
    // 获取状态栏、导航栏的Insets
    Insets insets = windowInsets.getInsets(WindowInsets.Type.systemBars());
    
    // 计算净尺寸:根视图宽高减去系统UI的左右、上下占用
    int usableWidth = view.getWidth() - insets.left - insets.right;
    int usableHeight = view.getHeight() - insets.top - insets.bottom;
    
    // 此处可使用计算出的净尺寸进行业务逻辑处理
    Log.d("WindowSize", "净宽度: " + usableWidth + ", 净高度: " + usableHeight);
    
    // 必须返回处理后的Insets,否则系统会反复调用该监听
    return windowInsets.consumeSystemWindowInsets();
});

2. 兼容Android 5到Android 10(API 21-29)

老设备可以通过ViewTreeObserver监听布局完成,再结合getWindowVisibleDisplayFrame获取可见区域:

View rootView = getWindow().getDecorView().getRootView();
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        // 移除监听避免重复触发
        rootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        
        // 获取屏幕整体尺寸
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        
        // 获取窗口实际可见区域(自动排除状态栏、导航栏,多窗口时也会排除外部区域)
        Rect visibleFrame = new Rect();
        getWindow().getDecorView().getWindowVisibleDisplayFrame(visibleFrame);
        
        // 净尺寸即为可见区域的宽高
        int usableWidth = visibleFrame.width();
        int usableHeight = visibleFrame.height();
        
        Log.d("WindowSize", "净宽度: " + usableWidth + ", 净高度: " + usableHeight);
    }
});

3. 三星弹窗模式适配说明

三星的弹窗模式属于Android多窗口的细分场景,上面两种方案都能自动适配——不管是WindowInsets还是getWindowVisibleDisplayFrame,都会识别弹窗的实际边界,返回对应的可用区域,无需额外编写适配代码。

注意事项

  • 不要在onCreate中直接获取尺寸!此时View还未完成布局,会得到0值,必须等View布局完成后通过监听获取
  • 如果是全屏隐藏状态栏/导航栏的场景,Insets会返回0,此时净尺寸就是根视图的实际宽高
  • 折叠屏设备同样适用这套逻辑,系统会自动处理折叠状态下的可用区域

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:22:52