一个Flutter widget自动适配不同UI到Web、Android

上图

webUI

androidUI

不是dp适配

对的,不是对dp的适配,而是在不同的分变率,改变布局的方式。大的屏幕肯定是要合理利用空间,这样布局紧凑,不浪费空间,小的屏幕又不能让大的组件等比压缩,这样不光会变丑,还会变的更难触及,既然Flutter对web的支持,那么肯定要支持不同分辨率,适配不同布局吧,就像我们Android开发,在针对Pad的时候做一个单独的xml布局来适配一样。

实现原理

原理很简单,就是在屏幕宽度到了一定范围内,然后动态返回不同的Widget,那么拿到屏幕的宽度就是关键,其实很简单

MediaQuery.of(context).size.width

详细介绍参见官方文档MediaQuery
大致意思是说,WidgetsAppMaterialApp目前只有它们引入了MediaQuery并随着它们的变化与当前屏幕指标保持最新,所以这也是为什么当你没有用这两个widget布局,最终报错的原因,用的时候注意。
我们来看个细节哈

WidgetsApp

MaterialApp

WidgetsAppMaterialApp
继承自StatefulWidget,我们平时写的组件也大部分都是继承自StatefulWidget,所以这就说明,你平时自己写的组件,如果是一个单独的新页面,当你用到这个MediaQuery时肯定会报错,不信你试试哈。
我们知道宽度后就好说了,只需要加入宽度判断就ok

  static bool isSmallScreen(BuildContext context) {
    return MediaQuery.of(context).size.width < 768;
  }

  static bool isLargeScreen(BuildContext context) {
    return MediaQuery.of(context).size.width > 768;
  }

  static bool isMediumScreen(BuildContext context) {
    return MediaQuery.of(context).size.width > 425 &&
        MediaQuery.of(context).size.width < 1200;
  }

然后在Widget build(BuildContext context)的时候返回不同的布局

 return LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.maxWidth > 768) {
          return largeScreen;
        } else if (constraints.maxWidth < 1200 && constraints.maxWidth > 425) {
          return mediumScreen ?? largeScreen;
        } else {
          return smallScreen ?? largeScreen;
        }
      },
    );

如何使用呢

  ConstrainedBox(
        constraints: BoxConstraints(
            minWidth: constraints.maxWidth, minHeight: constraints.maxHeight),
        child: ResponsiveWidget(
          largeScreen: _buildLargeScreen(context),
          mediumScreen: _buildMediumScreen(context),
          smallScreen: _buildSmallScreen(context),
        ),
      )

ConstrainedBox用于对子组件添加额外的约束,这里就是为了限制布局的宽高都充满屏幕,准确的说是充满父容器,保证计算的宽度不会出现失误。

官方动态适配方案

官方解读:
responsive响应式应用程序会根据屏幕或窗口的大小和形状来布局其UI。当同一个应用程序可以在各种设备(从手表,手机,平板电脑到笔记本电脑或台式机)上运行时,这尤其必要。当用户在笔记本电脑或台式机上调整窗口大小或更改手机或平板电脑的方向时,应用程序应通过相应地重新排列UI来做出响应。
官方推荐博客:

国外开源方案

image.png

responsive_builder这个框架的原理跟我介绍的一样,封装的会详细一些。请参考。

我介绍的方案地址

responsive_widget.dart

在线看效果

ibaozi.cn

结束

以后碰到Flutter中实用的东东,在分享给你们哈。欢迎留言讨论。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 国庆后面两天在家学习整理了一波flutter,基本把能撸过能看到的代码都过了一遍,此文篇幅较长,建议保存(star...
    Nealyang阅读 4,381评论 1 17
  • Flutter是开源并且免费的,拥有现代的响应式框架特性,高速的2D渲染引擎,方便快捷的开发工具以及各种开箱即用的...
    luehning阅读 587评论 0 0
  • 1、 Widget 基本概念 1、flutter中一切皆是Widget,不只是构建页面的UI,还有如布局类、事件处...
    风之化身呀阅读 1,499评论 0 0
  • 时光都一天天过去,新的明天又将迎来,就这样迎了小乔。 ...
    皇帝的简称阅读 378评论 1 0
  • 这个操作符可以用来快速的对 nil 进行判断,当左侧的值是 非 nil时返回其value左侧的值,为nil时返回其...
    GavinKang阅读 1,863评论 1 0