当前位置:   article > 正文

Flutter 中获取屏幕以及 Widget 的宽高

dart 获取窗口 宽高

我们平时在开发中的过程中通常都会获取屏幕或者 widget 的宽高用来做一些事情,在 Flutter 中,我们可以使用如下方法来获取屏幕或者 widget 的宽高。

MediaQuery

一般情况下,我们会使用如下方式去获取 widget 的宽高:

  1. final size =MediaQuery.of(context).size;
  2. final width =size.width;
  3. final height =size.height;
  4. 复制代码

但是如果不注意,这种写法很容易报错,例如下面的写法就会报错:

  1. import 'package:flutter/material.dart';
  2. class GetWidgetWidthAndHeiget extends StatelessWidget {
  3. @override
  4. Widget build(BuildContext context) {
  5. final size =MediaQuery.of(context).size;
  6. final width =size.width;
  7. final height =size.height;
  8. print('width is $width; height is $height');
  9. return MaterialApp(
  10. home: Scaffold(
  11. appBar: AppBar(
  12. title: Text('Width & Height'),
  13. ),
  14. body: Container(
  15. width: width / 2,
  16. height: height / 2,
  17. ),
  18. ),
  19. );
  20. }
  21. }
  22. 复制代码

在代码中,我们是想获取屏幕的宽和高,然后将屏幕宽高的一半分别赋值给 Container 的宽和高,但上述代码并不能成功运行,会报如下错误:

  1. flutter: The following assertion was thrown building GetWidgetWidthAndHeiget(dirty):
  2. flutter: MediaQuery.of() called with a context that does not contain a MediaQuery.
  3. flutter: No MediaQuery ancestor could be found starting from the context that was passed to MediaQuery.of().
  4. flutter: This can happen because you do not have a WidgetsApp or MaterialApp widget (those widgets introduce
  5. flutter: a MediaQuery), or it can happen if the context you use comes from a widget above those widgets.
  6. 复制代码

从错误异常中我们可以大概了解到有两种情况会导致上述异常:

  1. 当没有 WidgetsApp or MaterialApp 的时候,我们使用 MediaQuery.of(context) 来获取数据。
  2. 当我们在当前小部件中使用了上一个小部件的 context,来使用 MediaQuery.of(context) 获取数据的时候。

我们上述的代码很显然是属于第一种情况,也就是说我们在使用 MediaQuery.of(context) 的地方并没有一个 WidgetsApp or MaterialApp 来提供数据。

解决方法就是将 MediaQuery.of(context) 挪到 MaterialApp 内,如下:

  1. import 'package:flutter/material.dart';
  2. class GetWidgetWidthAndHeiget extends StatelessWidget {
  3. @override
  4. Widget build(BuildContext context) {
  5. return MaterialApp(
  6. home: HomePage(),
  7. );
  8. }
  9. }
  10. class HomePage extends StatelessWidget {
  11. @override
  12. Widget build(BuildContext context) {
  13. final size = MediaQuery.of(context).size;
  14. final width = size.width;
  15. final height = size.height;
  16. print('width is $width; height is $height');
  17. return Scaffold(
  18. appBar: AppBar(
  19. title: Text('Width & Height'),
  20. ),
  21. body: Center(
  22. child: Container(
  23. color: Colors.redAccent,
  24. width: width / 2,
  25. height: height / 2,
  26. ),
  27. ),
  28. );
  29. }
  30. }
  31. 复制代码

运行效果及输出如下:

  1. flutter: width is 414.0; height is 896.0
  2. 复制代码

上述代码中,我们获取的是 MaterialApp 的宽高,也就是屏幕的宽高

还有一种是直接使用 dart:ui 包中的 window 对象(这里非常感谢 XuYanjun Android @ 苏宁 提出的方法),这种方法使用起来也比较简单,如下:

  1. import 'dart:ui';
  2. final width = window.physicalSize.width;
  3. final height = window.physicalSize.height;
  4. 复制代码

那么如果我们要需要知道上述红色的 Container 容器的宽高怎么办呢?这里我们可以使用 GlobalKey

GlobalKey

使用 GlobalKey 的步骤如下:

  1. 声明一个 GlobalKey final GlobalKey globalKey = GlobalKey();

  2. 给 widget 设置 GlobalKey key: globalKey

  3. 通过 globalKey 来获取该 widget 的 size

    1. final containerWidth = globalKey.currentContext.size.width;
    2. final containerHeight = globalKey.currentContext.size.height;
    3. print('Container widht is $containerWidth, height is $containerHeight');
    4. 复制代码

修改过后的 HomePage 代码如下:

  1. class HomePage extends StatelessWidget {
  2. final GlobalKey globalKey = GlobalKey();
  3. void _getWH() {
  4. final containerWidth = globalKey.currentContext.size.width;
  5. final containerHeight = globalKey.currentContext.size.height;
  6. print('Container widht is $containerWidth, height is $containerHeight');
  7. }
  8. @override
  9. Widget build(BuildContext context) {
  10. final size = MediaQuery.of(context).size;
  11. final width = size.width;
  12. final height = size.height;
  13. print('width is $width; height is $height');
  14. return Scaffold(
  15. appBar: AppBar(
  16. title: Text('Width & Height'),
  17. ),
  18. body: Center(
  19. child: Container(
  20. key: globalKey,
  21. color: Colors.redAccent,
  22. width: width / 2,
  23. height: height / 2,
  24. ),
  25. ),
  26. floatingActionButton: FloatingActionButton(
  27. onPressed: _getWH,
  28. child: Icon(Icons.adjust),
  29. ),
  30. );
  31. }
  32. }
  33. 复制代码

上述代码中,我们将声明的 globalKey 设置给了 Container , 当我们点击页面中的 FloatingActionButton 的时候,就会使用 globalKey 来获取 Container 的宽高,也就是 _getWH() 中执行的代码。

运行结果及输出如下:

  1. flutter: Container widht is 207.0, height is 448.0
  2. 复制代码

如果错误,还请指出,谢谢

完整源码

参考链接

转载于:https://juejin.im/post/5c827600f265da2da67c5f06

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/227312
推荐阅读
相关标签
  

闽ICP备14008679号