Flutter Web:根据浏览器窗口改变布局大小

简介: 之前我们通过flutter开发web应用,然后用electron打包成可执行文件在pc端使用,因为electron可以设置最小宽高,所以布局不会越界,但是如果直接在浏览器中打开,因为浏览器的大小无法控制,如果用户缩小浏览器会导致布局越界。根据大部分网站的经验来看,当窗口缩小到一定程度后,布局就不会再改变,反而是增加了滚动,这样就保证了布局的正确性,所以我们也打算这么做。

前言


之前我们通过flutter开发web应用,然后用electron打包成可执行文件在pc端使用,因为electron可以设置最小宽高,所以布局不会越界,但是如果直接在浏览器中打开,因为浏览器的大小无法控制,如果用户缩小浏览器会导致布局越界。根据大部分网站的经验来看,当窗口缩小到一定程度后,布局就不会再改变,反而是增加了滚动,这样就保证了布局的正确性,所以我们也打算这么做。


监听窗口改变


经过测试,当浏览器窗口改变的时候,并不会执行页面的重绘,所以我们需要想办法监听窗口的改变。

这就需要用到window,先引入


import 'dart:html';
复制代码


然后通过window的onResize来监听,如下:


window.onResize.listen((event) {
  ...
});
复制代码


这里我们实现了监听,但是如何获取窗口的大小,同样还是用window


window.innerWidth
window.innerHeight
复制代码


这样就得到了窗口的大小。


实现滚动布局


滚动布局很简单,通过SingleChildScrollView即可,但是因为可能是两个方向的滚动,所以需要两个SingleChildScrollView嵌套。


Scrollbar(
  isAlwaysShown: true,
  child: SingleChildScrollView(
    scrollDirection: Axis.horizontal,
    child: SingleChildScrollView(
      child: appContent,
    ),
  ),
)
复制代码


这里第一个SingleChildScrollView是横向滚动,并且在外层给它添加了一个滚动条(因为windows机器的鼠标可能不支持横向滚动),然后里面在嵌套一个竖向滚动,最里面就是页面布局。


这样有一个问题,因为两层滚动所以整个布局是无限大的,加载真正的页面的时候就会报错:

RenderSemanticsAnnotations object was given an infinite size during layout.


所以我们要为页面大小加上宽高限制,首先想到的就是在Container的constraints中加入minHeight和minWidth,这是我们的目的


Scrollbar(
  isAlwaysShown: true,
  child: SingleChildScrollView(
    scrollDirection: Axis.horizontal,
    child: SingleChildScrollView(
      child: Container(
        constraints: BoxConstraints(
          minHeight: 720,
          minWidth: 1280
        ),
        child: widget.content,
      ),
    ),
  ),
)
复制代码


但是结果还是报错,因为虽然限制了宽高的最小值,最大值依然是无限大。所以还要加上最大值的限制?


我们可以继续在BoxConstraints中加上maxHeight和maxWidth,但是因为两个SingleChildScrollView导致整个空间是无限大的,所以页面会一直保持maxHeight和maxWidth,这样即使我们缩小一点浏览器而空间依然足够的情况下,页面就会需要滚动而不是压缩排列。


最终我们决定,通过计算来获取宽高,整体代码如下:


class AppContent extends StatefulWidget{
  Widget content;
  AppContent(this.content);
  @override
  State<StatefulWidget> createState() {
    return _AppContent();
  }
}
class _AppContent extends State<AppContent>{
  @override
  Widget build(BuildContext context) {
    return Scrollbar(
      isAlwaysShown: true,
      child: SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: SingleChildScrollView(
          child: Container(
            width: max(window.innerWidth.toDouble(), 1280),
            height: max(window.innerHeight.toDouble(), 720),
            child: widget.content,
          ),
        ),
      ),
    );
  }
  @override
  void initState() {
    window.onResize.listen((event) {
      setState(() {
      });
    });
  }
}
复制代码


可以看到,我们通过窗口大小与我们设置的最小尺寸进行比较取较大值,这样就保证了及时窗口很小页面也不会过小而引起越界,而且可以通过滚动来浏览整个页面。

然后我们在App中用AppContent包裹整个app的页面即可。


FittedBox替代


上面有两层滚动布局虽然可以实现我们的效果,但是在浏览器中实际效果不尽人意,因为两个方向上都有滚动,所以在操作时页面很容易移动,而且如果页面上有js拖动效果的(即在HtmlElementView中有一个div通过js实现拖动),在拖动div的同时页面也会跟着动,所以我尝试了更多的widget,最终决定用FittedBox替代,最终代码如下:


class AppContent extends StatefulWidget{
  Widget content;
  AppContent(this.content);
  @override
  State<StatefulWidget> createState() {
    return _AppContent();
  }
}
class _AppContent extends State<AppContent>{
  @override
  Widget build(BuildContext context) {
    return FittedBox(
      fit: BoxFit.cover,
      alignment: Alignment.topLeft,
      child: Container(
        width: max(window.innerWidth.toDouble(), 1280),
        height: max(window.innerHeight.toDouble(), 720),
        child: widget.content,
      ),
    );
  }
  @override
  void initState() {
    window.onResize.listen((event) {
      setState(() {
      });
    });
  }
}
复制代码


BoxFit.cover是按原尺寸填充,所以child可以超出FittedBox的范围。这样虽然不能滑动(如果窗口过小,即使可以滑动也不符合我们的业务需求,所以我们会建议用户全屏,这个仅仅是为了防止用户缩小窗口导致页面溢出错乱),但是页面不会出现溢出的现象。


替换成FittedBox后,滑动问题解决了。但是在浏览器中测试的实际效果与BoxFit.cover描述不太一致,当窗口缩小的时候,内部组件同步缩小了,当缩小到一定程度后才不会继续缩小,这时候页面才会开始显示部分。虽然与期望效果不一致,不过也无所谓,也算达到了需求要求。


目录
相关文章
|
1月前
|
JavaScript 前端开发 UED
JS:如何获取浏览器窗口尺寸?
JS:如何获取浏览器窗口尺寸?
37 1
|
2天前
|
开发框架 Dart 前端开发
【Flutter前端技术开发专栏】Flutter中的Web支持:构建跨平台Web应用
【4月更文挑战第30天】Flutter,Google的开源跨平台框架,已延伸至Web领域,让开发者能用同一代码库构建移动和Web应用。Flutter Web通过将Dart代码编译成JavaScript和WASM运行在Web上。尽管性能可能不及原生Web应用,但适合交互性强、UI复杂的应用。开发者应关注性能优化、兼容性测试,并利用Flutter的声明式UI、热重载等优势。随着其发展,Flutter Web为跨平台开发带来更多潜力。
【Flutter前端技术开发专栏】Flutter中的Web支持:构建跨平台Web应用
|
2天前
|
编解码 前端开发 开发者
【Flutter前端技术开发专栏】Flutter中的响应式设计与自适应布局
【4月更文挑战第30天】Flutter框架助力移动应用实现响应式设计与自适应布局,通过层次化布局系统和`Widget`树管理,结合`BoxConstraints`定义尺寸范围,实现自适应。利用`MediaQuery`获取设备信息,调整布局以适应不同屏幕。`FractionallySizedBox`按比例设定尺寸,`LayoutBuilder`动态计算布局。借助这些工具,开发者能创建跨屏幕尺寸、方向兼容的应用,提升用户体验。
【Flutter前端技术开发专栏】Flutter中的响应式设计与自适应布局
|
2天前
|
开发框架 前端开发 数据安全/隐私保护
【Flutter 前端技术开发专栏】Flutter 中的布局与样式设计
【4月更文挑战第30天】本文探讨了Flutter的布局和样式设计,关键点包括:1) 布局基础如Column、Row和Stack用于创建复杂结构;2) Container、Center和Expanded等常用组件的作用;3) Theme和Decoration实现全局样式和组件装饰;4) 实战应用如登录界面和列表页面的构建;5) 响应式布局利用MediaQuery和弹性组件适应不同屏幕;6) 性能优化,避免过度复杂设计。了解并掌握这些,有助于开发者创建高效美观的Flutter应用。
【Flutter 前端技术开发专栏】Flutter 中的布局与样式设计
|
6天前
|
编解码 算法 开发者
Flutter的布局系统:深入探索布局Widget与布局原则
【4月更文挑战第26天】Flutter布局系统详解,涵盖布局Widget(Row/Column、Stack、GridView/ListView、CustomSingleChildLayout)和布局原则(弹性布局、约束优先、流式布局、简洁明了)。文章旨在帮助开发者理解并运用Flutter的布局系统,创建适应性强、用户体验佳的界面。通过选择合适的布局Widget和遵循原则,可实现复杂且高效的UI设计。
|
15天前
|
Java 测试技术 定位技术
《手把手教你》系列技巧篇(二十三)-java+ selenium自动化测试-webdriver处理浏览器多窗口切换下卷(详细教程)
【4月更文挑战第15天】本文介绍了如何使用Selenium进行浏览器窗口切换以操作不同页面元素。首先,获取浏览器窗口句柄有两种方法:获取所有窗口句柄的集合和获取当前窗口句柄。然后,通过`switchTo().window()`方法切换到目标窗口句柄。在项目实战部分,给出了一个示例,展示了在百度首页、新闻页面和地图页面之间切换并输入文字的操作。最后,文章还探讨了在某些情况下可能出现的问题,并提供了一个简单的本地HTML页面示例来演示窗口切换的正确操作。
42 0
|
28天前
|
编解码 前端开发 开发者
构建响应式Web界面:Flexbox与Grid布局的深度对比
【4月更文挑战第4天】 在现代前端开发中,构建灵活且响应式的用户界面是至关重要的。随着移动设备浏览量的增加,能够适应不同屏幕尺寸和分辨率的布局技术变得必不可少。Flexbox和Grid是CSS提供的两种强大的布局机制,它们各自以独特的方式解决了响应式设计的挑战。本文将深入探讨Flexbox和Grid的核心概念、使用场景和性能考量,为开发者提供在面对不同布局需求时做出明智选择的依据。
|
2月前
|
前端开发 开发者 UED
构建响应式Web界面:Flexbox与Grid布局的深度解析
【2月更文挑战第28天】 在现代前端开发中,打造灵活且适应不同屏幕尺寸的用户界面是至关重要的。随着移动设备的普及,响应式设计已经成为网页制作不可或缺的一部分。本文将深入探讨两种强大的CSS布局模块——Flexbox和Grid,它们如何简化布局创建过程,并赋予设计师更大的灵活性去构建动态和流畅的响应式界面。通过对这两种技术的比较、使用场景分析以及代码示例,读者将能够更好地理解何时以及如何使用这些工具来提升前端项目的质量和效率。
19 0
|
2月前
|
编解码 前端开发 开发者
构建响应式Web界面:Flexbox布局的全面指南
【2月更文挑战第28天】 在当今多变的设备屏幕尺寸和分辨率中,创建一个能够适应不同视口的响应式Web界面至关重要。本文深入探讨了CSS Flexbox布局模块,它是一种设计灵活且强大的方式来创建复杂的响应式布局。我们将透过概念解析、关键属性讲解以及实际案例分析,帮助前端开发者掌握Flexbox的核心原理和应用技巧,以实现流畅的页面布局调整和优化用户体验。
|
2月前
|
前端开发 测试技术 开发者
构建响应式Web界面:Flexbox布局的力量
【2月更文挑战第24天】在现代Web开发中,创建能够适应不同屏幕尺寸的响应式界面已成为一项标准实践。Flexbox,一个CSS模块,因其灵活性和强大功能在前端开发者中广受欢迎。本文将深入探讨Flexbox的核心概念、常见用例以及如何利用它来构建美观、灵活且易于维护的响应式布局。通过实例演示,读者将学会如何有效地应用Flexbox技术,提升前端项目的质量和用户体验。

热门文章

最新文章