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

Flutter中如何获取物理屏幕尺寸而非窗口尺寸?

解决Linux下Flutter窗口管理器获取物理显示器宽度的问题

问题核心

你当前通过MediaQuery.of(context).size获取的是当前窗口的尺寸,而非物理显示器的真实分辨率;同时在build方法中直接调用windowManager.setSize时机不合理,导致无法正确设置全屏宽度。

可行解决方案

方案1:使用screen_retriever包(推荐)

这个包是window_manager的配套工具,专门用于获取系统显示器信息,完美适配Linux平台。

步骤1:添加依赖

在pubspec.yaml中加入:

dependencies:
  flutter:
    sdk: flutter
  window_manager: ^0.3.8
  screen_retriever: ^0.1.11

步骤2:修改代码

import 'package:flutter/material.dart';
import 'package:window_manager/window_manager.dart';
import 'package:screen_retriever/screen_retriever.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await windowManager.ensureInitialized();
  
  runApp(const Headbar());
}

class Headbar extends StatelessWidget {
  const Headbar({super.key});

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _setupWindow(),
      builder: (context, snapshot) {
        return const MaterialApp(
          home: Scaffold(
            body: Center(
              child: Text('Hello World!'),
            ),
          ),
        );
      },
    );
  }

  Future<void> _setupWindow() async {
    await windowManager.waitUntilReadyToShow();
    // 获取主屏幕的物理宽度
    final primaryScreen = await screenRetriever.getPrimaryDisplay();
    final screenWidth = primaryScreen.size.width;
    
    // 按顺序配置窗口
    await windowManager.setTitleBarStyle(TitleBarStyle.hidden);
    await windowManager.setPosition(const Offset(0, 0));
    await windowManager.setSize(Size(screenWidth, 50));
    await windowManager.setResizable(false);
    await windowManager.setSkipTaskbar(true);
    await windowManager.show();
  }
}

关键说明

  • 先完成Flutter绑定和窗口管理器初始化,避免上下文未就绪的问题
  • 通过screen_retriever直接获取物理屏幕的真实分辨率,而非窗口尺寸
  • 先设置窗口尺寸,再禁用调整大小,解决之前setResizable破坏尺寸设置的问题

方案2:调用Linux系统命令(无额外依赖)

如果不想引入新包,可以通过xrandr命令解析屏幕尺寸:

import 'dart:io';

Future<double> getLinuxScreenWidth() async {
  final processResult = await Process.run('xrandr', ['--query']);
  final output = processResult.stdout.toString();
  // 匹配主屏幕的分辨率格式
  final resolutionRegex = RegExp(r'(\d+)x(\d+)\+\d+\+\d+.*primary');
  final match = resolutionRegex.firstMatch(output);
  if (match != null) {
    return double.parse(match.group(1)!);
  }
  return 1920; // 兜底默认值
}

将上述方法替换方案1中获取screenWidth的逻辑即可,但该方法依赖系统环境,兼容性不如专用包。

内容的提问来源于stack exchange,提问作者CStafford-14

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:48:29