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

MediaQuery

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

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

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

import 'package:flutter/material.dart';

class GetWidgetWidthAndHeiget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final size =MediaQuery.of(context).size;
final width =size.width;
final height =size.height;
print('width is $width; height is $height');
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Width & Height'),
),
body: Container(
width: width / 2,
height: height / 2,
),
),
);
}
}
复制代码

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

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

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

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

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

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

import 'package:flutter/material.dart';

class GetWidgetWidthAndHeiget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
} class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final width = size.width;
final height = size.height;
print('width is $width; height is $height');
return Scaffold(
appBar: AppBar(
title: Text('Width & Height'),
),
body: Center(
child: Container(
color: Colors.redAccent,
width: width / 2,
height: height / 2,
),
),
);
}
}
复制代码

运行效果及输出如下:

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

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

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

import 'dart:ui';

final width = window.physicalSize.width;
final height = window.physicalSize.height;
复制代码

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

GlobalKey

使用 GlobalKey 的步骤如下:

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

  2. 给 widget 设置 GlobalKey key: globalKey

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

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

修改过后的 HomePage 代码如下:

class HomePage extends StatelessWidget {

  final GlobalKey globalKey = GlobalKey();

  void _getWH() {
final containerWidth = globalKey.currentContext.size.width;
final containerHeight = globalKey.currentContext.size.height;
print('Container widht is $containerWidth, height is $containerHeight');
} @override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final width = size.width;
final height = size.height;
print('width is $width; height is $height');
return Scaffold(
appBar: AppBar(
title: Text('Width & Height'),
),
body: Center(
child: Container(
key: globalKey,
color: Colors.redAccent,
width: width / 2,
height: height / 2,
),
),
floatingActionButton: FloatingActionButton(
onPressed: _getWH,
child: Icon(Icons.adjust),
),
);
}
}
复制代码

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

运行结果及输出如下:

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

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

完整源码

参考链接

Flutter获取屏幕宽高和Widget大小的更多相关文章

  1. android获取屏幕宽高与获取控件宽高

    获取屏幕宽高 // 获取屏幕宽高(方法1) int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); // 屏幕宽(像素 ...

  2. vue 获取屏幕宽高 width height

    /**  * 获取屏幕宽高  */ Vue.prototype.getViewportSize = function(){   return {     width: window.innerWidt ...

  3. android 获取屏幕宽高 和 获取控件坐标

    一.获取屏幕宽高: (1). WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE); int width ...

  4. js获取屏幕宽高

    最近想自己实现一个全屏滚动. 结果一开始就遇到了问题.因为不知道如何获取一个页面屏幕的高度. 网上所有的博客都是复制粘贴. 网页可见区域宽:document.body.clientWidth 网页可见 ...

  5. 【Html】网页获取屏幕宽高

    <html> <script> function size(){ document.write( "屏幕分辨率为:"+screen.width+" ...

  6. js 获取屏幕宽高

    网页可见区域宽: document.body.clientWidth 网页可见区域高: document.body.clientHeight 网页可见区域宽: document.body.offset ...

  7. js、jq获取屏幕宽高

    参考资料 JS,Jquery获取各种屏幕的宽度和高度

  8. js 获取图片宽高 和 图片大小

    获取要查看大小的img var img_url = 'http://img5.imgtn.bdimg.com/it/u=4267222417,1017407570&fm=200&gp= ...

  9. Swift 获取屏幕宽高

    let screenh = UIScreen.mainScreen().applicationFrame.size.heightlet screenw = UIScreen.mainScreen(). ...

随机推荐

  1. 学习笔记01(mybatis逆向工程)

    今天来看看一个常用的小功能,就是mybatis的逆向工程.(数据库是mysql) 什么是逆向工程呢?看名字就知道反方向的一个什么工程! 其实啊,如果是平常我们自己学习实践一些小项目的时候,应该是先瞎写 ...

  2. Python实战171203统计

    统计序列中元素出现的频次 如何统计出某一个随机数列的元素出现的次数是多少? import randomdata=[random.randint(0,7) for _ in range(15)]c=di ...

  3. jquery快速入门(三)

    捕获内容和属性 1.DOM 操作 获得内容 - text().html() 以及 val() text() - 设置或返回所选元素的文本内容,如果不带值则是返回值,如果带值则是修改值,如:$('p') ...

  4. Docker进阶之八:搭建LNMP网站平台实战

    搭建LNMP网站平台实战 LNMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写.L指Linux,N指Nginx,M一般指MySQL,也可以指MariaDB,P一般指PHP,也可 ...

  5. SLAM+语音机器人DIY系列:(三)感知与大脑——3.轮式里程计与运动控制

    摘要 在我的想象中机器人首先应该能自由的走来走去,然后应该能流利的与主人对话.朝着这个理想,我准备设计一个能自由行走,并且可以与人语音对话的机器人.实现的关键是让机器人能通过传感器感知周围环境,并通过 ...

  6. 【转载】解析 java 按值传递还是按引用传递

    原文链接  说明: (1):“在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递. (2):在Java里面只有基本类型和 ...

  7. 基础概念PHP-FPM、FastCGI和CGI

    在搭建 LAMP/LNMP 服务器时,会经常遇到 PHP-FPM.FastCGI和CGI 这几个概念.如果对它们一知半解,很难搭建出高性能的服务器.接下来我们就以图形方式,解释这些概念之间的关系. 基 ...

  8. java的设计模式 - 单例模式

    java 面试中单例模式基本都是必考的,都有最推荐的方式,也不知道问来干嘛.下面记录一下 饿汉式(也不知道为何叫这个名字) public class Singleton { private stati ...

  9. 网页三剑客:HTML+CSS+JavaScript 之JavaScript

    JavaScript 简介 JavaScript 是互联网上最流行的脚本语言,这门语言可用于 HTML 和 web,更可广泛用于服务器.PC.笔记本电脑.平板电脑和智能手机等设备. JavaScrip ...

  10. Vue项目需求实现记录(永久更新)

    1.表单校验功能: 在el-form标签中定义:rules="rules";ref="reference" 在el-form-item定义prop=" ...