这是在Flutter中构建布局的指南。首先,您将构建以下屏幕截图的布局。然后回过头, 本指南将解释Flutter的布局方法,并说明如何在屏幕上放置一个widget。在讨论如何水平和垂直放置widget之后,会介绍一些最常见的布局widget:

如果你想对布局机制有一个“全貌”的理解,请参考Flutter的布局方法

第0步:创建应用程序基代码

1, 获取代码: 创建一个基本的“Hello World”Fluuer应用程序。

2.更改应用程序栏标题和应用程序标题,如下所示:

Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter layout demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: AppBar(
title: Text('Flutter layout demo'),
),
body: new Center(
child: new Text('Hello World'),
),
),
);
}

接下来,将图像添加到示例中:

  • 在工程根目录创建一个 images 文件夹.
  • 添加 lake.jpg. (请注意,wget不能保存此二进制文件。)
  • 更新 pubspec.yaml 文件以包含 assets 标签. 这样才会使您的图片在代码中可用。

第一步: 绘制布局图

第一步是将布局拆分成基本的元素:

  • 找出行和列.
  • 布局包含网格吗?
  • 有重叠的元素吗?
  • 是否需要选项卡?
  • 注意需要对齐、填充和边框的区域.

首先,确定更大的元素。在这个例子中,四个元素排列成一列:一个图像,两个行和一个文本块

接下来,绘制每一行。第一行称其为标题部分,有三个子项:一列文字,一个星形图标和一个数字。它的第一个子项,列,包含2行文字。 第一列占用大量空间,所以它必须包装在Expanded widget中。

第二行称其为按钮部分,也有3个子项:每个子项都是一个包含图标和文本的列。

一旦拆分好布局,最简单的就是采取自下而上的方法来实现它。为了最大限度地减少深度嵌套布局代码的视觉混淆,将一些实现放置在变量和函数中。

第二步: 实现标题行

首先,将在标题部分构建左列。在myapp类的build()方法的顶部添加以下代码:

Widget titleSection = Container(
padding: const EdgeInsets.all(32),
child: Row(
children: [
Expanded(
/**/
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/**/
Container(
padding: const EdgeInsets.only(bottom: 8),
child: Text(
'Oeschinen Lake Campground',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
Text(
'Kandersteg, Switzerland',
style: TextStyle(
color: Colors.grey[500],
),
),
],
),
),
/**/
Icon(
Icons.star,
color: Colors.red[500],
),
Text('41'),
],
),
);

将Column(列)放入Expanded中会拉伸该列以使用该行中的所有剩余空闲空间。 设置crossAxisAlignment属性值为CrossAxisAlignment.start,这会将该列中的子项左对齐。

将第一行文本放入Container中,然后底部添加8像素填充。列中的第二个子项(也是文本)显示为灰色。

标题行中的最后两项是一个红色的星形图标和文字“41”。将整行放在容器中,并沿着每个边缘填充32像素。

将标题部分添加替换到应用程序主体,如下所示:

    return MaterialApp(
title: 'Flutter layout demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: AppBar(
title: Text('Flutter layout demo'),
),
body: Column(
children: [
titleSection,
],
),
),
);

如果有问题,请将代码与lib/main.dart进行比较。

第3步: 实现按钮行

按钮部分包含3个使用相同布局的列 - 上面一个图标,下面一行文本。该行中的列平均分布行空间, 文本和图标颜色为主题中的primary color,它在应用程序的build()方法中设置为蓝色:

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//... return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
), //...
}

由于构建每一列的代码几乎相同,因此创建一个嵌套函数,如buildButtonColumn,它会创建一个颜色为primary color,包含一个Icon和Text的 Widget 列。

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// ···
} Column _buildButtonColumn(Color color, IconData icon, String label) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, color: color),
Container(
margin: const EdgeInsets.only(top: ),
child: Text(
label,
style: TextStyle(
fontSize: ,
fontWeight: FontWeight.w400,
color: color,
),
),
),
],
);
}
}

构建函数将图标直接添加到列(Column)中。将文本放入容器以在文本上方添加填充,将其与图标分开。

通过调用函数并传递特定于该列的颜色、图标和文本,生成包含这些列的行。使用mainaxisalignment.space沿主轴对齐各列,使每列前后的自由空间均匀排列。在build()方法内的titleSection声明下方添加以下代码:

Color color = Theme.of(context).primaryColor;

Widget buttonSection = Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildButtonColumn(color, Icons.call, 'CALL'),
_buildButtonColumn(color, Icons.near_me, 'ROUTE'),
_buildButtonColumn(color, Icons.share, 'SHARE'),
],
),
);

将按钮部分添加到正文:

    body: Column(
children: [
titleSection,
buttonSection,
],
),

如果有问题,请将代码与lib/main.dart进行比较。

第4步:实现文本部分

将文本部分定义为变量。将文本放入容器中,并沿每个边缘添加填充。在buttonsection声明的正下方添加以下代码:

Widget textSection = Container(
padding: const EdgeInsets.all(),
child: Text(
'Lake Oeschinen lies at the foot of the Blüemlisalp in the Bernese '
'Alps. Situated 1,578 meters above sea level, it is one of the '
'larger Alpine Lakes. A gondola ride from Kandersteg, followed by a '
'half-hour walk through pastures and pine forest, leads you to the '
'lake, which warms to 20 degrees Celsius in the summer. Activities '
'enjoyed here include rowing, and riding the summer toboggan run.',
softWrap: true,
),
);

通过将softwrap设置为true,文本行将在换行前填充列宽。

将文本部分添加到正文:

    body: Column(
children: [
titleSection,
buttonSection, //将按钮部分添加到正文
textSection, //将文本部分添加到正文
],
),

如果有问题,请将代码与lib/main.dart进行比较。

第5步:实现图像部分

四列元素中的三个现在已经完成,只剩下图像部分。该图片可以在Creative Commons许可下在线获得, 但是它非常大,且下载缓慢。在步骤0中,您已经将该图像包含在项目中并更新了pubspec文件,所以现在可以从代码中直接引用它:

    children: [
Image.asset(
'images/lake.jpg',
width: ,
height: ,
fit: BoxFit.cover,
), //从代码中引用图像
titleSection,
buttonSection, //将按钮部分添加到正文
textSection, //将文本部分添加到正文
],

BoxFit.cover 告诉框架,图像应该尽可能小,但覆盖整个渲染框.

如果有问题,请将代码与lib/main.dart进行比较。

第6步: 整合

在最后一步中,将所有元素排列在ListView中,而不是列中,因为当应用程序在小型设备上运行时,ListView支持应用程序主体滚动。

    body: new ListView(
children: [
Image.asset(
'images/lake.jpg',
width: ,
height: ,
fit: BoxFit.cover,
), //从代码中引用图像
titleSection,
buttonSection, //将按钮部分添加到正文
textSection, //将文本部分添加到正文
],
),

Dart code: main.dart
Image: images
Pubspec: pubspec.yaml

结束了!当您热重载应用程序时,就会看到和截图中相同界面。您可以参考 给Flutter APP 添加交互来给您的应用添加交互。

在Flutter中构建布局的更多相关文章

  1. flutter中的生命周期函数

    前言:生命周期是一个组件加载到卸载的整个周期,熟悉生命周期可以让我们在合适的时机做该做的事情,flutter中的State生命周期和android以及React Native的生命周期类似. 先看一张 ...

  2. mvp 在 flutter 中的应用

    在 Android 应用程序开发过程中,我们经常会用到一些所谓的架构方法,如:mvp,mvvm,clean等.之所以这些方法会被推崇是因为他们可以大大的解耦我们的代码的功能模块,让我们的代码在项目中后 ...

  3. 聊聊flutter的UI布局

    UI布局多半是套路,熟悉套路的规则. Flutter的UI布局也有一套规则 center center可以让任何元素在屏幕中居中,既是水平居中又是垂直居中,如果想让元素从上而下排列要怎么办呢?那就得使 ...

  4. Flutter 中文文档网站 flutter.cn 正式发布!

    在通常的对 Flutter 介绍中,最耳熟能详的是下面四个特点: 精美 (Beautiful):充分的赋予和发挥设计师的创造力和想象力,让你真正掌控屏幕上的每一个像素. ** 极速 (Fast)**: ...

  5. 理解 Flutter 中的 Key

    概览 在 Flutter 中,大概大家都知道如何更新界面视图: 通过修改 Stata 去触发 Widget 重建,触发和更新的操作是 Flutter 框架做的. 但是有时即使修改了 State,Flu ...

  6. Flutter中的基础组件之一

    一.Text文本组件(单一格式的文本) 是具有单一风格的文本字符串,可以跨多行显示,也可全部显示在同一行中,具体显示样子,取决于布局约束. 常用属性: 1.overflow : TextOverflo ...

  7. flutter中的列表组件

    列表布局是我们项目开发中最常用的一种布局方式.Flutter 中我们可以通过 ListView 来定义列表项,支持垂直和水平方向展示.通过一个属性就可以控制列表的显示方向.列表有以下分类:  垂直列表 ...

  8. Flutter样式和布局控件简析(二)

    开始 继续接着分析Flutter相关的样式和布局控件,但是这次内容难度感觉比较高,怕有分析不到位的地方,所以这次仅仅当做一个参考,大家最好可以自己阅读一下代码,应该会有更深的体会. Sliver布局 ...

  9. Flutter中Expanded组件用法

    Flutter中Expanded组件用法 Expanded组件可以使Row.Column.Flex等子组件在其主轴方向上展开并填充可用空间(例如,Row在水平方向,Column在垂直方向).如果多个子 ...

随机推荐

  1. Http 缓存剖析

    缓存一直是前端优化的主战场, 利用好缓存就成功了一半. 本篇从http请求和响应的头域入手, 让你对浏览器缓存有个整体的概念. 最终你会发现强缓存, 协商缓存 和 启发式缓存是如此的简单. 导读 浏览 ...

  2. Fastdfs集群搭建

    1.关于集群,网上说最少要三台,其实也没必要,两台就够了 2.实验环境 192.168.2.201 tracker.storage.nginx + fastdfs-nginx-module-maste ...

  3. tableviewer自动调整列宽

    public void resizeTableColumn(TableColumn[] treeColumns) { for (TableColumn tc : treeColumns) tc.pac ...

  4. 收藏!了解UART总线工作原理看这一篇就够了!

    原文:玩转单片机 2019-08-24 16:50:29 越学到后面,基础知识更加不能忘记,温故而知新~~ 还记得当年的打印机,鼠标和调制解调器吗?他们都有巨大笨重的连接器和粗电缆,并且必须拧到你的电 ...

  5. pandas处理json脱坑(二)--jsonError: Expecting ',' delimiter: line 1 column 2674

    Expecting ',' delimiter: line 1 column 2674 json_dict = json.loads(row[json_columns].replace("' ...

  6. Oracle - 特殊字符问题

    Oracle更新表字段或者查询表字段时内容中含有特殊字符&的解决方法 现象 解决方式 1. 字符串拼接 UPDATE T_MENU_INFO SET menu_code='/ABeptjk/g ...

  7. [Luogu] 跑路

    https://www.luogu.org/problemnew/show/P1613 Floyd判断是否一步到达 将一步到达的连变跑Floyd #include <iostream> # ...

  8. Gym - 102307D Do Not Try This Problem

     Do Not Try This Problem Gym - 102307D 题意:给个长度为len的字符串(len<=1e5),然后q次操作(q<=1e5),每次给出i,a,k,c,(i ...

  9. MySQL数据分析-(6)数据库设计之规范化

    大家好,我是jacky,很高兴继续跟大家学习MySQL数据分析这门课,上次课我们介绍了E-R图,我们要给手机销售公司设计数据库,那么同一个项目,10个设计人员可能设计出10种不同的E-R图:因为不同的 ...

  10. TCP首部的TimeStamp时间戳选项 转载

    TCP应该是以太网协议族中被应用最为广泛的协议之中的一个,这里就聊一聊TCP协议中的TimeStamp选项.这个选项是由RFC 1323引入的,该C建议提交于1992年.到今天已经足足有20个年头.只 ...