likes
comments
collection
share

Flutter之构建布局

作者站长头像
站长
· 阅读数 21
你会学到什么
· Flutter的布局机制是如何工作的。
· 如何垂直和水平布置小部件。
· 如何创建Flutter布局。

本篇博客介绍绘制下面的布局: Flutter之构建布局

step0: 创建应用程序基本代码

确保您的Flutter环境已经安装完成,然后执行以下操作:

  1. 创建一个新的Flutter应用程序。
  2. 将其中的内容替换lib/main.dart为以下代码:
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
    const MyApp({Key? key}) : super(key: key);
    
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            title: 'Flutter layout demo',
            home: Scaffold(
                appBar: AppBar(
                    title: const Text('Flutter layout demo'),
                ),
                body: const Center(
                    child: Text('Hello World'),
                ),
            ),
        );
    }
}

step1: 绘制布局图

第一步是将布局分解为基本元素:

  • 识别行和列
  • 布局是否包含网格?
  • 是否有重叠元素?
  • UI是否需要选项卡?
  • 注意需要哦对齐、填充或边框的区域

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

Flutter之构建布局

接下来,绘制每一行。第一行称为标题部分,有3个子项:一列文本、一个星形图标和数字。它的第一个孩子,列,包含2行文本。第一列占用大量空间,因此必须将其包装在Expanded小部件中。

Flutter之构建布局 第二行,称为Button部分,也有3个子项:每个子项都是一个包含图标和文本的列。

Flutter之构建布局 绘制布局图后,最容易采用自下而上的方法来实施它。为了尽量减少深层嵌套布局代码的视觉混乱,将一些实现放在变量和函数中。

step2: 实现标题行

首先,您将在标题部分构建左栏。在MyApp类的build()方法顶部添加以下代码: lib/main.dart

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

/*1*/将Column放在Expanded小部件中会拉伸该列以使用该行中所有剩余的可用空间。将crossAxisAlignment属性设置为CrossAxisAlignment.start将列定位在行的开头

/*2*/将第一行文本放在Container中可以添加填充。Column中的第二个子项,也是文本,显示为灰色 。

/*3*/标题行中的最后两项是星形图标,设置为红色,以及文本“41”。正好都在容器中,并沿每条边填充32像素。将标题部分添加到应用程序正文中,如下所示:

Flutter之构建布局

step3: 实现按钮行

按钮部分包含3列,它们使用相同的布局——行文本上方的一个图标。该行中的列间距均匀,文本和标题使用原色绘制。

由于构建每一列的代码几乎相同,因此创建一个名为buildButtonColumn()的私有辅助方法 ,它采用一种颜色、一个图标和文本,并返回一个列,其小部件以给定颜色绘制。

class MyApp extends StatelessWidget {
    const MyApp({Key? key}) : super(key: key);
    
    @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: 8),
                    child: Text(
                        label,
                        style: TextStyle(
                            fontSize: 12,
                            fontWeight: FontWeight.w400,
                            color: color,
                        ),
                    ),
                ),
            ],
        );
    }
}

该函数将图标直接添加到列中。文本位于Container内,只有顶部间距,将文本与图标分开。

通过调用函数并传递特定位于该列的颜色、图标和文本来构建包含这些列的行。使用MainAxisAlignment.spaceEvenly沿主轴对齐列,以在每列之前、之间和之后均匀地排列可用空间。在build()方法中的titleSection声明下方添加以下代码: lib/main.dart (buttonSection)

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

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

将按钮部分添加到body:

Flutter之构建布局

step4: 实现文本部分

将文本部分定义为变量。将文本放入Container并沿每条边添加填充。在buttonSection声明下方添加以下代码: lib/main.dart (textSection)

Widget textSection = const Padding(
    padding: EdgeInsets.all(32),
    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:

Flutter之构建布局

step5: 实现图像部分

四个列元素中的三个现已完成,只留下图像。将图像文件添加到示例中:

  • 在项目顶部创建一个asset目录。
  • 添加 lake.jpg
  • 更新pubspec.yaml文件以包含asset标签。这使图像可用于您的代码。

Flutter之构建布局

Flutter之构建布局

现在您可以从代码中引用图像:

Flutter之构建布局 BoxFit.cover告诉框架图像应该尽可能小但覆盖它的整个渲染框。

step6: 最后重构一下

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

Flutter之构建布局 Dart code:  main.dart Image:  images Pubspec:  pubspec.yaml

就是这样!当您hot reload夹在应用程序时,您应该会看到与顶部截图相同的应用程序布局。

转载自:https://juejin.cn/post/7192593306109526074
评论
请登录