Flutter Row 实例 —— 新手礼包

在这里插入图片描述

大家好,我是 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 的常用的用法就都介绍完了。谢谢观看!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

靠近用户侧和数据,算网融合实现极致协同

游弋自如的生产力,在边缘。IMMENSE、36氪|作者 1846年1月,纽约。 一行长短不一的电码顺着通讯线路飞往130公里开外的费城,这是华尔街的巨头们首次使用电报传输讯息,更具有金钱意味的是,电力通讯的成功&am…

【蓝桥杯集训·周赛】AcWing 第96场周赛

文章目录第一题 AcWing 4876. 完美数一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解第二题 AcWing 4877. 最大价值一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解第三题 AcWing 4878. 维护数组一、题目1、原…

路由策略实验

运行OSPF协议 [R1]ospf 1 router-id 1.1.1.1 [R1-ospf-1]area 0 [R1-ospf-1-area-0.0.0.0]network 192.168.12.1 0.0.0.0 [R1-ospf-1-area-0.0.0.0]network 192.168.13.1 0.0.0.0 [R2]ospf 1 router-id 2.2.2.2 [R2-ospf-1]area 0 [R2-ospf-1-area-0.0.0.0]network 192.168.…

抖音seo矩阵系统源码搭建技术+二开开源代码定制部署

抖音已经成为了当今最为流行的短视频平台之一,拥有着庞大的用户群体和海量的视频资源。对于一些商家或者运营者来说,如何从这些视频资源中挖掘出有效的信息,进而提升自己的品牌、产品或者内容的曝光度,就成为了一个非常重要的问题…

一次通过.frm和.ibd恢复mysql数据表的过程

1、导出.frm和.ibd文件 2、安装Mysql的Utilities 3、执行命令(实际恢复的表) mysqlfrm --diagnostic ./stat_vehicle_mileage.frm4、复制Sql,添加ROW_FORMATCOMPACT(需要检测生成的Sql语句是否可用) CREATE TABLE …

Android开发-Android常用组件-ProgressBar进度条

4.8 ProgressBar进度条 常用属性 android:max 进度条的最大值 android:progress 进度条已完成进度值 android:progressDrawable 设置轨道对应的Drawable对象 android:indeterminate 如果设置成true,则进度条不精确显示进度 android:indeterminateDrawable …

YOLO算法改进指南【算法解读篇】:2.如何训练自己的数据集

我们接着上一篇文章配置完YOLOv5需要的环境后,今天我们试着用YOLOv5训练自己的数据。(在开始本教程前,记得先跑一遍入门篇,确保环境是正常的) 有图有真相,先看看我的运行结果 【YOLOv5 源码地址】 🚀 我的环境: 语言环境:Python3.8编译器:PyCharm深度学习环境: to…

2021蓝桥杯真题格点(填空题) C语言/C++

问题描述 如果一个点(x,y) 的两维坐标都是整数, 即 x∈Z 且 y∈Z, 则称这个点为 一个格点。 如果一个点 (x,y) 的两维坐标都是正数, 即 x>0 且 y>0, 则称这个点在 第一象限。 请问在第一象限的格点中, 有多少个点(x,y) 的两维坐标乘积不超过 2021 , 即x⋅y≤2021 。 掟…

c#之反射详解

总目录 文章目录总目录一、反射是什么?1、C#编译运行过程2、反射与元数据3、反射的优缺点二、反射的使用1、反射相关的类和命名空间1、System.Type类的应用2、System.Activator类的应用3、System.Reflection.Assembly类的应用4、System.Reflection.Module类的应用5、…

SpringBoot 整合RabbitMq 自定义消息监听容器来实现消息批量处理

SpringBoot 整合RabbitMq 自定义消息监听容器来实现消息批量处理前言添加依赖配置文件编写监听器创建SimpleRabbitListenerContainerFactory发送消息前言 RabbitMQ是一种常用的消息队列,Spring Boot对其进行了深度的整合,可以快速地实现消息的发送和接收…

PCB模块化设计16——RS232,RS485接口模块PCB布局布线设计规范

目录PCB模块化设计16——RS232,RS485接口模块PCB布局布线设计规范RS232接口模块1、接口概述2、接口电路 原理图的EMC设计3、连接器设计4、线缆设计5、RS-232常规管脚定义:6、RS-232知识要点RS485接口模块1、原理图设计方案1、RS485接口6KV防雷电路设计方…

c语言程序笔记(1)

C语言笔记&#xff08;1&#xff09;——B站翁恺视频 程序框架 #include <stdio.h> int main() {//printf("hello world!\n");return 0; }1、变量与常量。 例子1&#xff1a; #include <stdio.h> int main() {printf("1234%d",1234);return …

图解LeetCode——合并两个有序链表

如果你喜欢这篇文章的话&#xff0c;请给作者点赞关注哟&#xff0c;你的支持是我不断前进的动力&#xff01; 目录 题目描述&#xff1a; 解法&#xff1a; 完整代码&#xff1a; 结果 题目链接&#xff1a;力扣 题目描述&#xff1a; 将两个升序链表合并为一个新的 升序…

2017世界互联网领先成果来了 光量子计算机

演讲者&#xff1a;陆朝阳中国科学技术大学教授 发布了世界上首台超越早期经典计算机的光量子计算机 陆朝阳&#xff1a;很高兴向大家报告中国科学院在量子计算这个领域取得的基础性的研究成果。 我们知道50多年以来摩尔定律一直见证着计算机的更新换代&#xff0c;之前每过18个…

【新2023Q2模拟题JAVA】华为OD机试 - 绘图机器

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:绘图机器 题目 绘图机器的绘…

读书笔记-纳瓦尔宝典-2023.04.01

重点 财富 如何构造高价值信息 判断力 何为幸福 启发 最近看了这本书的大部分内容&#xff0c;感悟颇多&#xff0c;及时记录下来。 因为是快速阅读&#xff0c;还未做深入思考和实践&#xff0c;但对总体的内容有一个大致把握&#xff0c;未来会结合行动反复阅读和思考&…

python画爱心代码

前几天在网上看到了一个画爱心的教程&#xff0c;就是在 Python里面画一个爱心&#xff0c;但是我在网上找到的代码不是很好用&#xff0c;所以我就自己写了一遍。 首先我们先创建一个新的 python文件。新建一个 python文件夹&#xff0c;将我们之前的那个 python文件夹复制到这…

蓝桥杯·3月份刷题集训Day03

本篇博客旨在记录自已打卡蓝桥杯3月份刷题集训&#xff0c;同时会有自己的思路及代码解答希望可以给小伙伴一些帮助。本人也是算法小白&#xff0c;水平有限&#xff0c;如果文章中有什么错误之处&#xff0c;希望小伙伴们可以在评论区指出来&#xff0c;共勉&#x1f4aa;。 文…

2021年第十二届蓝桥杯省赛Java B组真题及详细题解

A试题 : ASC【填空题】 本题总分&#xff1a; 5 分 【1、问题描述】 已知大写字母 A 的 ASCII 码为 65&#xff0c;请问大写字母 L 的 ASCII 码是多少&#xff1f; 【2、答案提交】 这是一道结果填空的题&#xff0c;你只需要算出结果后提交即可。本题的结果为一个整数&#…

二十、Javascript API(一)

1. Atomics和SharedArrayBuffer 多个上下文访问 SharedArrayBuffer时&#xff0c;如果同时对缓冲区执行操作&#xff0c;就可能出现资源争用问题。Atomics API 通过强制同一时刻只能对缓冲区执行一个操作&#xff0c;可以让多个上下文安全地读写一个SharedArrayBuffer。 1.1 …