Flutter Row 实例 —— 新手礼包

news2024/11/8 15:12:33

在这里插入图片描述

大家好,我是 17。

本文在 3.31 日全站综合热榜第一。
在这里插入图片描述

新手礼包一共 3 篇文章,每篇都是描述尽量详细,实例讲解,包会!

  • Flutter Row 实例 —— 新手礼包
  • Flutter TextField UI 实例 —— 新手礼包
  • Flutter TextField 交互实例 —— 新手礼包

本篇介绍 Row 的用法,用实例讲解 flex 弹性布局原理。本来在 Flutter 弹性布局的基石: Flex 和 Flexible 一文中的内容已经包含 Row 了,但因为 Row 太常用了,所以单写一篇。

Row 的尺寸

默认情况下, Row 在宽度上尽量大,在高度上只要能包住所有的 children 即可。

第一个示例给出全部代码,后面的只给出 Row 的代码。在 Row 的外面加一个 Container ,是为了给 Row 加一个 border,方便查看。减去 margin,padding,border 后 ,Row 的宽度为 300。

MaterialApp(
  home: Scaffold(
     body: Container(
         width: 342,
         alignment: Alignment.center,
         child: Container(
             padding: const EdgeInsets.all(10),
             margin: const EdgeInsets.all(10),
             decoration:
                 BoxDecoration(border: Border.all(color: Colors.blue)),
             child: Row(
               children: [
                 Container(
                   width: 100,
                   height: 50,
                   color: const Color.fromARGB(255, 82, 143, 222),
                 ),
               ],
             )))));

在本例中,Row 的宽度达到允许的最大值 300。高度为 50,正好可以包含蓝色块的高度。MainAxisSize.min 可以让 Row 的宽度也正好能包含 children。

Row(
    mainAxisSize: MainAxisSize.min,
    children: [
      Container(
        width: 100,
        height: 50,
        color: const Color.fromARGB(255, 82, 143, 222),
      ),
    ],
  );

mainAxisSize:MainAxisSize.min 让 Row 的宽度收缩,直到正好包含 所有 children 为止。本例中,正好包含蓝色块,最终宽度为 100。

mainAxisSize 的默认值是 mainAxisSize.max

非弹性布局

非弹性布局是说在 children 中没有 Expanded,Flexible 这种有 flex 参数的 child。

Row(
    children: [
      Container(
        width: 100,
        height: 50,
        color: const Color.fromARGB(255, 82, 143, 222),
      ),
      const Text(
        "IAM17",
        style:
            TextStyle(color: Color(0xFFC45F84), fontSize: 24),
      )
    ],
);

非弹性布局中,Row 的 children 在宽度方面没有限制, child 按自己期望的尺寸在水平方向依次排列。如果 children 的总宽度没有超过 Row 的宽度,没有什么问题。如果超过了 Row 的宽度,在开发环境下,会给出警告。

比如修改 Container 的 width:100width:400,这个时候 Row 已经没有多余的空间给 Text 了,甚是连 Container 也放不下。

在生产环境中,多出来的部分会被直接截断。

弹性布局

弹性布局是说在 children 中有 Expanded,Flexible 这种有 flex 参数的 child。

简单来说,Row 分配空间的过程是这样的。

  1. 先分配非弹性 child,比如 Container,Text,这些没有 flex 属性的 Widget。
  2. 把剩余的空间按 flex 值的大小,分给所有的弹性块。
  3. 如果是用 Expanded 包起来的 child, child 的大小就是 第 2 步分配空间的大小;如果是用 Flexible 包起来,child 的大小可以从 0 到 第 2 步分配空间的大小 之间自行决定。

这里说的 Flexible 的 fit 参数的值为 FlexFit.loose。Expanded 就是 fit 参数为 FlexFit.tight 的 Flexible。

让 child 占用所有分配到的空间,用 Expanded 包起来

Row(
   children: [
     Expanded(
         child: Container(
       width: 100,
       height: 50,
       color: const Color.fromARGB(255, 82, 143, 222),
     )),
     const Text(
       "IAM17",
       style:
           TextStyle(color: Color(0xFFC45F84), fontSize: 24),
     )
   ],
 )

Row 的宽度为 300,先给非弹性块 Text 分配固定大小空间,剩余的全分给的 Expanded。child 蓝色块占用所有 Expanded 分配到的空间。

我们注意到 Container 的 width 是 100,实际上,就算是这里写 0,或写 1000 都没有关系,用 Expanded 包起来的 child 的 width 属性会被忽略。

Expanded 包起来的 child 的 width 是不能自定义的,如果 child 要自定义 width 又要保持弹性布局怎么办?用 Flexible!

让 child 可以在分配到的空间内自行决定大小,用 Flexible 包起来。

在下面的例子中 Row 总的可用宽度为 300,两个 Container 各占 100,还余 100 空白在两个 Container 之间

Row(
     mainAxisAlignment: MainAxisAlignment.spaceBetween,
     children: [
       Container(
         width: 100,
         height: 50,
         color: Colors.blue,
       ),
       Container(
         width: 100,
         height: 50,
         color: Colors.red,
       ),
     ],
   )

现在我们把第一个 container 用 Flexible 包起来。

Row(
     mainAxisAlignment: MainAxisAlignment.spaceBetween,
     children: [
       Flexible(
           child: Container(
         width: 100,
         height: 50,
         color: Colors.blue,
       )),
       Container(
         width: 100,
         height: 50,
         color: Colors.red,
       ),
     ],
   )

重新执行查看效果,发现没什么变化。这是因为 总宽度为 300,分给非弹性红色块 100后还有 200, 唯一的弹性块拿到 200。蓝色块的 100 在分配到的空间范围内,所以没有什么反应。

把第一个 Container 的 width 加大到 150 查看效果,发现第一个 Container 的宽度变为 150 了。同理 150 也在 分配到的 200 之内。

继续加大 width 的宽度到 200,发现他们已经紧贴到一起了。继续加大就没有任何效果了,但也不会报错。

继续加大到 200 以上就超过分配到的 200了,所以宽度不再增加。不会报错是因为蓝色块被 Flexible 限制在 200 以内,加上红色块的总宽度在 300 以内,没有超出,当然不会报错。

如果左面 Container 的 宽度不是我们指定的,而是 Container 的 child 撑起来的,那么就可以实现宽度自适应的布局效果,不用担心会超出边界。

Flexible 的 flex 与 fit 参数

Flexible 的 flex 决定了可以分配多少剩余空间。fit 参数决定 child 能否自行决定大小。

看下面的的例子,红色块为固定宽度,绿蓝为弹性宽度。在fit: FlexFit.tight 的情况下,绿色块和红色块的 width 无效。因为 Flexible 的 flex 已经决定了宽度值,child 只能用这个值不能修改。

Row(children: [
     Container(
             width: 20, height: 50, color: Colors.red),
     Flexible(
         fit: FlexFit.tight,
         flex: 1,
         child: Container(
             width: 100, height: 50, color: Colors.green)),
     Flexible(
         fit: FlexFit.tight,
         flex: 2,
         child: Container(
             width: 100, height: 50, color: Colors.blue))
   ]

本例中 Row 的宽度为 320,首先分配 20 给固定宽度的红色块,剩余的 300 由两个弹性块瓜分。根据 flex 值,绿色块得到 100,蓝色块得到 200。Flex 值越大,得到的空间越大。

fit: FlexFit.tight 的 Flexible ,一般是用 Expanded。

fit: FlexFit.loose 的情况下,绿色块和红色块的 width 是有作用的,可以在 0 和最大值之间自定义自己的宽度。

我们把第二个 Flexible 的 fit: FlexFit.tight 修改为 fit: FlexFit.loose,蓝色块的 width 起作用了,显示为 100 宽。

我们调整一下摆放方式,蓝色块省出来的 100 空间被填充到各个块之间了。

 child: Row(
     mainAxisAlignment: MainAxisAlignment.spaceBetween,
     ...

在 children 之间加空白。

在 children 之间增加固定空白用 SizedBox

我们发现 Container 和 文本紧挨在一起了,想要他们之间有一个距离。可以用 Padding 把 Container 或 Text 包起来,但是这样写起来比较麻烦,而且多了一个层级,也不美观,不如用 SizedBox。

Row(
   children: [
      Container(
        width: 100,
        height: 50,
        color: const Color.fromARGB(255, 82, 143, 222),
      ),
      const SizedBox(width: 20,),
      const Text(
        "IAM17",
        style:
            TextStyle(color: Color(0xFFC45F84), fontSize: 24),
      )
    ],
  )

在 children 之间增加弹性空白用 Spacer

 Row(
     children: [
        Container(
         width: 100,
         height: 50,
         color: const Color.fromARGB(255, 82, 143, 222),
       ),
       const Spacer(),
       const Text(
         "IAM17",
         style:
             TextStyle(color: Color(0xFFC45F84), fontSize: 24),
       )
     ],
   )

文本 “IAM17” 与 蓝色块 之间的空白是 文本 “IAM17” 与 文本 “Flutter” 之间空白宽度的两倍。Row 的宽度如果增加或缩小,空白的宽度也会增加会缩小,但会保持两倍的关系。

平均分配空白

平均分配空白用 mainAxisAlignment 参数,具体用法详见 Flutter Wrap 图例。虽然讲的是 Wrap Widget,但是 alignment 与 Row 的 mainAxisAlignment 用法是一样的。比如两端对齐:

Row(
   mainAxisAlignment: MainAxisAlignment.spaceBetween,
   ...

Row 嵌套

Row 嵌套的时候需要注意下,因为一不小心会报错。

Row(
     children: [
       Row(children: [
         Expanded(
             child: Container(
           width: 100,
           height: 50,
           color: Color.fromARGB(255, 210, 74, 137),
         ))
       ]),
     ],
   )

Expanded 是要占据所有的可用空间,内层的 Row 在宽度可以是无限,Expanded 无法占据无限空间,所以报错。解决的办法很简单,让 内层的 Row 的宽度有限就可以了。

Row(
   children: [
     Expanded(
         child: Row(children: [
       Expanded(
           child: Container(
         width: 100,
         height: 50,
         color: Color.fromARGB(255, 210, 74, 137),
       ))
     ])),
   ],
 )

或者给 Row 加一个宽度约束。比如用 SizedBox 包起来。

Row(
   children: [
     SizedBox(
         width: 150,
         child: Row(children: [
           Expanded(
               child: Container(
             width: 100,
             height: 50,
             color: Color.fromARGB(255, 210, 74, 137),
           ))
         ])),
   ],
 );

用 Flexible 包起来也是可以的,Flexible 与 Expanded 的区别在于 Flexible 给 child loose 约束,Expanded 给 child tight 约束。通俗一点的说法是 Flexible 的 child 的宽度可以从 0 到 最大值之间自己决定。Expanded 的 child 的宽度只能是固定值,不能修改。

Row 嵌套的时候报错本质上是因为宽度无限,遇到其它宽度无限的场景也会出现这样的问题,比如 ListView 横向滚动的时候,把 Row 嵌套在 ListView 中也会有类似的问题。

ListView(
     scrollDirection: Axis.horizontal,
     children: [
       Row(children: [
         Expanded(
             child: Container(
           width: 100,
           height: 50,
           color: Color.fromARGB(255, 210, 74, 137),
         ))
       ]),
     ],
   )

解决办法相同,也是把 Row 用 Flexible 或 Expanded 包起来,或加一个宽度约束。

ListView(
    scrollDirection: Axis.horizontal,
    children: [
      Expanded(
          child: Row(children: [
        Expanded(
            child: Container(
          width: 100,
          height: 50,
          color: Color.fromARGB(255, 210, 74, 137),
        ))
      ])),
    ],
  );

到这里 Flutter Row 的常用的用法就都介绍完了。谢谢观看!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/421076.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CDN如何成为大站标配?

在当下的互联网应用中充斥了大量的静态内容,这些静态和准动态内容在访问请求中占据了大量的网络资源,如果这些请求全部指向源站服务器,很容易导致网络的拥塞甚至是服务器的宕机,对正常的业务开展造成严重影响。为了解决这种情况&a…

共享电子邮件的运作方式

通过电子邮件共享,您可以使用评论轻松管理围绕电子邮件展开的讨论,而无需多次转发和回复。这提供了一种轻松的方式,让您可以通过电子邮件与同事分享信息,并获得他们对此的意见/反馈/建议。 电子邮件共享的运作方式 您收到或发送的…

开源流媒体服务器ZLMediaKit在Windows上运行、配置、按需拉流拉取摄像头rtsp视频流)并使用http-flv网页播放

场景 目前市面上有很多开源的流媒体服务器解决方案,常见的有SRS、EasyDarwin、ZLMediaKit和Monibuca等。 1、SRS GitHub - ossrs/srs: SRS is a simple, high efficiency and realtime video server, supports RTMP, WebRTC, HLS, HTTP-FLV, SRT, MPEG-DASH and …

【linux】 安装 java 环境

目录1.检查linux 下是否安装java(jdk)环境2.查看 linux 的操作系统版本3.下载jdk4.新建java文件夹用于安装jdk5.将下载到本地的jdk压缩包上传到linux服务器6.配置环境变量1.检查linux 下是否安装java(jdk)环境 可通过下面五条命令来查看linux 系统是否安装了java 环境 1、java …

$ZZZ 以 Launchpad 形式多平台首发,GoSleep 成 Sleep to Earn 叙事成 X2E 新宠

“ GoSleep 的治理代币 $ZZZ 将以 Launchpad 形式登录 Bitget、Gate.io以及MXC,这或许预示着 Sleep to Earn 叙事或成 X2E 新宠” “Sleep to Earn” 成为 X2E 市场新发力点 StepN 在去年为 X2E 赛道做了一个很好的示范,这也让这个领域不再仅仅局限于基于…

HarmonyOS/OpenHarmony应用开发-Stage模型ArkTS语言Ability基类

Ability模块提供对Ability生命周期、上下文环境等调用管理的能力,包括Ability创建、销毁、转储客户端信息等。 说明: 模块首批接口从API version 9 开始支持。模块接口仅可在Stage模型下使用。 导入模块: import Ability from ohos.app.ability.Ability; 接口说明…

虚拟化技术:实现资源高效利用和灵活管理的利器

虚拟化技术是一种通过软件或硬件手段,将物理资源抽象化,从而创建虚拟资源的技术。这种技术可以应用于计算、存储、网络等领域,通过将物理资源划分为多个虚拟资源,使得多个应用程序或用户可以共享同一组物理资源,从而提…

面试官:说说Java、Spring、Dubbo三者SPI机制的原理和区别

今天来跟大家聊一聊Java、Spring、Dubbo三者SPI机制的原理和区别。 其实我之前写过一篇类似的文章,但是这篇文章主要是剖析dubbo的SPI机制的源码,中间只是简单地介绍了一下Java、Spring的SPI机制,并没有进行深入,所以本篇就来深入…

数据结构2:顺序表和链表

目录 1.线性表 2.顺序表 2.1概念及结构 2.2接口实现 2.3数据相关面试题 2.4顺序表的问题及思考 3.链表 3.1链表的概念及结构 3.2链表的分类 3.3链表的实现 3.4链表面试题 3.5双向链表的实现 4.顺序表和链表的区别 1.线性表 线性表(linear list&#x…

Qt QImage scaled方法缩放中的问题

最近在某些测试中发现,QImage 先按照一定的比例进行缩放,在对QImage对象进行绘制等操作后,使用以下的方式将其恢复到其原来的尺寸。 图像的缩放是这样的: void ImageBaseWidget::zoomImage(QMouseEvent *event) {if (event->…

传输层协议——TCP协议

传输层协议——TCP协议认识IP地址TCP/IP的分层管理TCP/IP分层通信示例(发送数据包)认识IP地址 IP地址属于网络层地址 在计算机通信中,为了识别通信对端,必须有一个类似于地址的识别码进行标识。IP地址用于在连接到网络中的所有主…

利用seaborn、statannotations库绘制显著性标注

如何使用Python-SeabornSeaborn进行显著性统计图表绘制,详细内容如下: Python-Seaborn自定义函数绘制Python-statannotations库添加显著性标注 1、Python-Seaborn 自定义函数绘制 import matplotlib.pylab as plt import numpy as np import seaborn as…

Spring Cloud组件源码之LoadBalancer源码分析

" Spring 到底是春天的来临万物复苏,还是春转夏的干燥又炎热呢?" Spring的来临让JavaEE走向了另一个高度。便捷的开发,完美的生态。物极必反,学习Spring的成本越来越低,导致Java程序员越来越密集&#xff0…

1、Windows下编译并搭建AzerothCore服务端

目录前言一、AzerothCore下载二、mysql安装三、boost安装四、OpenSSL安装五、CMake下载六、CMake编译1 - CMake生成vs项目2 - vs项目设置3 - 生成解决方案4 - 安装AzerothCore5 - 添加账号6 - 修改服务器名称7 - 修改客户端的服务器地址前言 客户端对应版本:魔兽世…

CANopen | 对象字典OD 07 - 创建对象字典变量,变量变化时发送TPDO1,滤波时间200ms

文章目录一、前言二、实验目的三、对象字典OD四、TPDO1数据变化发送,滤波时间200ms4.1、main.c4.2、让CANopen从站进入操作状态4.3、TPDO1的CAN数据包一、前言 该笔记的程序:github 二、实验目的 CANopen从站有一个变量tx_Value,映射到T…

我调用第三方接口遇到的13大坑

前言 在实际工作中,我们经常需要在项目中调用第三方API接口,获取数据,或者上报数据,进行数据交换和通信。 那么,调用第三方API接口会遇到哪些问题?如何解决这些问题呢? 这篇文章就跟大家一起…

ubuntu防火墙命令介绍

ubuntu在开启ufw防火墙前,为了避免与iptables现有规则冲突,建议先清空iptables的所有规则。相关命令如下: iptables -F 更改iptables规则链默认操作命令如下: iptables -P INPUT ACCEPTiptables -P FORWARD ACCEPTiptables -P …

【PyTorch】第一节:张量(Tensor)的定义

作者🕵️‍♂️:让机器理解语言か 专栏🎇:PyTorch 描述🎨:PyTorch 是一个基于 Torch 的 Python 开源机器学习库。 寄语💓:🐾没有白走的路,每一步都算数&#…

云原生网络之微隔离

本博客地址:https://security.blog.csdn.net/article/details/130044619 一、微隔离介绍 1.1、微隔离概念 在主体执行动作时,对主体权限和行为进行判断,最常见的是网络访问控制,也就是零信任网络访问(ZTNA&#xff…

TP5 解决如何实现生成并导出Word文档功能

今天连续更新两篇文章,上一篇讲了一下如何生成PDF并导出文件的功能 接下来我们就来拼一拼怎么实现生成并导出word文档的功能 话不多说 我们直接上流程: 1.下载安装phpword插件:composer require phpoffice/phpword 2.安装成功后该插件在我们项…