用Flutter进行UI开发

哈Ha! 引起您的注意,文章“ 建筑布局 ”的翻译。

今天我们发现:


  • Flutter UI构建器如何工作
  • 如何水平和垂直布置屏幕
  • 如何使用Flutter弥补屏幕

今天课程的结果将是以下屏幕布局

图片


步骤0:项目设置


首先,创建一个新项目File-> New Flutter Project-> next,next,next ...
接下来,在项目的根目录中创建images目录,并在其中放置一个名为lake.jpg的文件-您可以从此处下载文件- 链接

还必须修复配置文件pubspec.yaml(类似于android的gradle和iOS中的可可豆荚,我们可以在其中添加外部依赖项)。 文件本身的文本可以在此处下载

可以在此处下载项目源-必须将其放置在main.dart文件中

步骤1:屏幕图表


首先,将布局分解为简单元素

  • 定义行和列
  • 确定布局是否包含网格?
  • 是否有任何重叠的元素
  • 我需要用户界面的选项卡吗?
  • 注意需要对齐或缩进的区域

首先,我们确定主要的大要素。 在此示例中,一列排列了4个元素:图片,两行和一个测试块

图片

接下来,我们将分析每一行。 第一行称为“标题”,有3个子级-一列文字,一个星形图标和一个数字。 第一列包含2行。 第一列占用大量空间,因此您应该将其包装在可扩展的小部件中。

图片

下一行称为按钮部分,也有3个孩子。 它们每个都包含图片和文本。

图片

最后,我们将布局布局为简单元素。 使用“自下而上”方法进行显示布局的最简单方法。 为了避免复杂的结构,请将UI分为变量和函数。

步骤2:建立标题行


首先,我们需要构建标题部分的左列。 在可扩展窗口小部件中插入一列将扩展该列以使用该行中所有剩余的空间。 将crossAxisAlignment属性设置为CrossAxisAlignment.start,以使列与行的开头对齐。

在容器内放置一行文本可以激活填充。 列中的第二个孩子也是文本,显示为灰色。 最后两个元素标有红色的“星形”图标和值为“ 41”的文本。 将整行放置在容器中,并在每侧添加32像素的缩进。 下面介绍了完成这些步骤的代码。

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { Widget titleSection = Container( padding: const EdgeInsets.all(32.0), child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.only(bottom: 8.0), 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'), ], ), ); //... } 

步骤3:建立一系列按钮


按钮部分由3列组成,它们根据类似的原理构建-一行文本上方的图标。 该行中的列均匀填充,并且以主要颜色绘制文本和图标,在build()方法中,该颜色在我们的项目中被选择为蓝色。

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

由于每一行的构造代码几乎相同,因此使用嵌套函数(例如buildButtonColumn())将是最有效的,该函数包含一个图标和文本,并使用此小部件返回一列。

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

构建功能将图标直接添加到列中。 将文本放在容器中以添加填充并将其与图标分开。 我们通过调用函数并在列内传递图标和文本来构造这些列的每一行。 甚至使用MainAxisAlignment.space沿主轴对齐列,组织每列之前,之间和之后的可用空间。

 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { //... Widget buttonSection = Container( child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ buildButtonColumn(Icons.call, 'CALL'), buildButtonColumn(Icons.near_me, 'ROUTE'), buildButtonColumn(Icons.share, 'SHARE'), ], ), ); //... } 

步骤4:构建描述部分


定义一个很长的描述部分。 将文本放置在容器中,并从每个边缘添加32像素缩进。

 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { //... Widget textSection = Container( padding: const EdgeInsets.all(32.0), 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, ), ); //... } 

步骤5:构建图像部分


四个列中的三个已经建立,仅保留为image列。 该项目中使用的图像可在知识共享许可下在线获得。 但是它很大,加载速度很慢。 在第0步中,我们将图像添加到了项目中并更新了配置文件,现在我们将在代码中添加指向该图像的链接。

 return MaterialApp( //... body: ListView( children: [ Image.asset( 'images/lake.jpg', height: 240.0, fit: BoxFit.cover, ), // ... ], ), //... ); 

BoxFit.cover告诉Flutter框架,图像应尽可能小,同时仍要覆盖整个渲染区域。

步骤6:将所有内容放在一起


在最后一步,我们将收集所有代码。 该窗口小部件是在ListView中组织的,而不是在Column中组织的,因为ListView在小型设备上滚动时会自动滚动。

 //... return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: Scaffold( appBar: AppBar( title: Text('Top Lakes'), ), body: ListView( children: [ Image.asset( 'images/lake.jpg', width: 600.0, height: 240.0, fit: BoxFit.cover, ), titleSection, buttonSection, textSection, ], ), ), ); //... 

Source: https://habr.com/ru/post/zh-CN433256/


All Articles