Flutter - 布局(Layouts)

Flutter - 布局(Layouts) 首页 / Flutter入门教程 / Flutter - 布局(Layouts)

布局机制的主要概念是小部件。无涯教程知道Flutter将一切都作为小部件。所以图像(image),图标(icon),文本(text),甚至应用程序的布局都是所有小部件。在这里,您在App UI上不可见的一些布局,例如row,columns,constrain等小部件。

Flutter允许无涯教程通过组合多个窗口小部件以构建更复杂的窗口小部件来创建布局。例如,无涯教程可以看到下面的图像,其中显示了三个图标,每个图标下方都有一个标签。

Flutter Layouts

在第二张图片中,无涯教程可以看到上面图片的视觉布局。此图显示了三列的行,这些列包含一个图标(icon)和标签(label)。

Flutter Layouts

在上图中, container 是一个窗口小部件,允许无涯教程自定义子窗口小部件。它主要用于添加边界(borders),填充(padding),边距(margin),背景颜色(background color)等等。在这里,文本窗口(Text widget)小部件位于集合(Container)下方,以添加边距。整行也都放置在集合中,以增加行边距(margin)和填充(padding)。另外,UI的其余部分由color,text.style等属性控制。

布局小部件

让无涯教程了解无涯教程如何创建和显示一个简单的小部件。以下步骤显示如何布局窗口小部件:

步骤1:  首先,您需要选择一个布局窗口小部件。

步骤2:  接下来,创建一个可见的小部件。

步骤3:  然后,将可见窗口小部件添加到布局小部件。

步骤4:  最后,将布局小部件添加到要显示的页面。

布局部件类型

无涯教程可以将布局小组用具分为两种类型:

  1. Single Child Widget(单个子部件)
  2. Multiple Child Widget(多个子部件)

Single Child Widget

单个子布局小部件是一种类型的小部件,在父布局小部件内只能有一个子小部件。这些小部件还可以包含特殊的布局函数。 Flutter为无涯教程提供了许多单子小部件,以使应用程序UI更具吸引力。如果无涯教程适当地使用这些小部件,它可以节省无涯教程的时间并使应用程序代码更具可读性。单个子窗口小部件的不同类型的列表为:

无涯教程网

Container   - 它是最流行的布局小部件,为小部件的绘制(painting),定位(positioning)和大小(sizing)提供可自定义的选项。

Center(
  child: Container(
    margin: const EdgeInsets.all(15.0),
    color: Colors.blue,
    width: 42.0,
    height: 42.0,
  ),
)

Padding    -  它是一个小部件,用于通过填充(padding)来排列其子小部件。它包含EdgeInsets和EdgeInsets.fromLTRB,用于在提供填充的所需空间。

const Greetings(
  child: Padding(
    padding: EdgeInsets.all(14.0),
    child: Text('Hello Learnfk!'),
  ),
)

Center   -  此小部件可让您将子小部件置于其内部居中。

Align      -  它是一个小部件,它在其内部对齐其子部件,并根据子部件的大小对其进行调整。

Center(
  child: Container(
    height: 110.0,
    width: 110.0,
    color: Colors.blue,
    child: Align(
      alignment: Alignment.topLeft,
      child: FlutterLogo(
        size: 50,
      ),
    ),
  ),
)

SizeBox   -  此小部件可让您在所有屏幕上为子小部件指定大小。

SizedBox(
  width: 300.0,
  height: 450.0,
  child: const Card(child: Text('Hello Learnfk!')),
)

AspectRatio   -  此小部件可让您将子小部件的大小保持为指定的宽高比。

AspectRatio(
  aspectRatio: 5/3,
  child: Container(
    color: Colors.bluel,
  ),
),

Baseline        -   该窗口小部件根据子基线移动子窗口小部件。

child: Baseline(
         baseline: 30.0,
         baselineType: TextBaseline.alphabetic,
         child: Container(
              height: 60,
              width: 50,
              color: Colors.blue,
         ),
)

ConstramedBox    -  它是一个小部件,可让您对其子小部件附加约束。这意味着您可以强制子部件具有特定的约束,而无需更改子部件的属性。

ConstrainedBox(
  constraints: new BoxConstraints(
    minHeight: 150.0,
    minWidth: 150.0,
    maxHeight: 300.0,
    maxWidth: 300.0,
  ),
  child: new DecoratedBox(
    decoration: new BoxDecoration(color: Colors.red),
  ),
),

CustomSingleChildLayout   -  它是一个小部件,可以将单个子布局推迟到委托。委托决定放置子部件的位置,还用于确定父窗口小部件的大小。

FittedBox                                    -  它根据指定的适合度缩放和定位子窗口小部件。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
 //它是您的应用程序的根小部件。
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Multiple Layout Widget',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
       //这是您的应用程序的主题。
        primarySwatch: Colors.green,
      ),
      home: MyHomePage(),
    );
  }
}
class MyHomePage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("FittedBox Widget")),
        body: Center(
        child: FittedBox(child: Row(
          children: [
            Container(
              child: Image.asset('assets/computer.png'),
              ),
              Container(
                child: Text("This is a widget"),
              )
            ],
          ),
          fit: BoxFit.contain,
        )
      ),
    );
  }
}

输出

Flutter Layouts

FractionallySizedBox                        -   它是一个小部件,允许根据可用空间的比例调整其子小部件的大小。

IntrinsicHeight和IntrinsicWidth  -   它们是一个小部件,可让无涯教程将其子小部件的大小调整为子部件的固有高度和宽度。

LimitedBox                                            -   这个小部件允许无涯教程仅在不受限制的情况下限制其大小。

Offstage                                                   -   它用于测量窗口小部件的尺寸,而无需将其显示在屏幕上。

OverflowBox                                          -   它是一个小部件,允许对其子部件施加与从父部件获得的约束不同的约束。

例子

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
 //它是您的应用程序的根小部件。
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Single Layout Widget',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
       //This is the theme of your application.
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}
class MyHomePage extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("OverflowBox Widget"),
      ),
      body: Center(
      child: Container(
        height: 50.0,
        width: 50.0,
        color: Colors.red,
        child: OverflowBox(
          minHeight: 70.0,
          minWidth: 70.0,
          child: Container(
            height: 50.0,
            width: 50.0,
            color: Colors.blue,
            ),
          ),
        ),
      ),
    );
  }
}

输出

Flutter Layouts

Multiple Child Widgets

多个子窗口小部件是一种窗口小部件,其中包含多个子窗口小部件,并且这些窗口小部件的布局是唯一的。例如,“Row”窗口小部件在水平方向上从其子窗口小部件布局,而“Column”窗口小部件在垂直方向上从其子窗口小部件布局。如果无涯教程将“Row”和“Column”窗口小部件组合在一起,则它可以构建任何级别的复杂窗口小部件。

在这里,无涯教程将学习不同类型的多个子窗口小部件:

Row    -  它允许沿水平方向排列其子窗口小部件。

例子

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
 //它是您的应用程序的根小部件。
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Multiple Layout Widget',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
       //This is the theme of your application.
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        alignment: Alignment.center,
        color: Colors.white,
        child: Row(
          children: [
            Expanded(
              child: Text('Peter', textAlign: TextAlign.center),
            ),
            Expanded(
              child: Text('Learnfk', textAlign: TextAlign.center ),

            ),
            Expanded(
              child: FittedBox(
                fit: BoxFit.contain,//otherwise the logo will be tiny
                child: const FlutterLogo(),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

输出

Flutter Layouts

Column        -   它允许在垂直方向上排列其子窗口小部件。

ListView      -   它是最流行的滚动小部件,它使无涯教程可以在滚动方向上一个接一个地排列其子小部件。

GridView     -   它使无涯教程能够将其子窗口小部件排列为可滚动的2D窗口小部件阵列。它由以水平和垂直布局排列的单元的重复图案组成。

Expanded    -   它允许使“行(Row)和列(Column)”窗口小部件的子级占据最大可能面积。

Table             -   它是一个小部件,允许无涯教程在基于表的小部件中排列其子级。

Flow              -   它允许无涯教程实现基于流的窗口小部件。

Stack             -   它是必不可少的小部件,主要用于重叠多个子小部件。它允许您将多层放置到屏幕上。以下示例有助于理解它。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
 //它是您的应用程序的根小部件。
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Multiple Layout Widget',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
       //This is the theme of your application.
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        alignment: Alignment.center,
        color: Colors.white,
        child: Stack(
          children: [
           //Max Size
            Container(
              color: Colors.blue,
            ),
            Container(
              color: Colors.pink,
              height: 400.0,
              width: 300.0,
            ),
            Container(
              color: Colors.yellow,
              height: 220.0,
              width: 200.0,
            )
          ],
        ),
      ),
    );
  }
}

输出

Flutter Layouts

建立复杂布局

在本节中,无涯教程将学习如何使用单个和多个子布局小部件创建复杂的用户界面。布局框架允许您通过在行和列内嵌套行和列来创建复杂的用户界面布局。

让无涯教程通过创建product list 来查看复杂用户界面的示例。为此目的,您需要首先替换具有以下代码片段的 main.dart 文件的代码。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
 //It is the root widget of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo Application', theme: ThemeData(
      primarySwatch: Colors.green,),
      home: MyHomePage(title: 'Complex layout example'),
    );
  }
}
class MyHomePage extends StatelessWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("Product List")),
        body: ListView(
          padding: const EdgeInsets.fromLTRB(3.0, 12.0, 3.0, 12.0),
          children: [
            ProductBox(
                name: "iPhone",
                description: "iPhone is the top branded phone ever",
                price: 55000,
                image: "iphone.png"
            ),
            ProductBox(
                name: "Android",
                description: "Android is a very stylish phone",
                price: 10000,
                image: "android.png"
            ),
            ProductBox(
                name: "Tablet",
                description: "Tablet is a popular device for official meetings",
                price: 25000,
                image: "tablet.png"
            ),
            ProductBox(
                name: "Laptop",
                description: "Laptop is most famous electronic device",
                price: 35000,
                image: "laptop.png"
            ),
            ProductBox(
                name: "Desktop",
                description: "Desktop is most popular for regular use",
                price: 10000,
                image: "computer.png"
            ),
          ],
        )
    );
  }
}
class ProductBox extends StatelessWidget {
  ProductBox({Key key, this.name, this.description, this.price, this.image}) :
        super(key: key);
  final String name;
  final String description;
  final int price;
  final String image;

  Widget build(BuildContext context) {
    return Container(
        padding: EdgeInsets.all(2),
        height: 110,
        child: Card(
            child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Image.asset("assets/" + image),
                  Expanded(
                      child: Container(
                          padding: EdgeInsets.all(5),
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                            children: [
                              Text(
                                  this.name, style: TextStyle(
                                  fontWeight: FontWeight.bold
                              )
                              ),
                              Text(this.description), Text(
                                  "Price: " + this.price.toString()
                              ),
                            ],
                          )
                      )
                  )
                ]
            )
        )
    );
  }
}

在上面的代码中,无涯教程创建了一个窗口小部件ProductBox,其中包含产品的详细信息,例如图像(image),名称(name),价格(price)和描述(description)。在ProductBox小部件中,无涯教程使用以下子小部件:容器(Container),行(Row),列(Column),扩展(Expanded),卡片(Card),文本(Text),图像(Image)等。此小部件包含以下布局:

Flutter Layouts

现在,当无涯教程在Android仿真器中运行Dart文件时,它将提供以下输出。

Flutter Layouts

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

Linux实战技能100讲 -〔尹会生〕

编译原理之美 -〔宫文学〕

后端存储实战课 -〔李玥〕

用户体验设计实战课 -〔相辉〕

Django快速开发实战 -〔吕召刚〕

人人都用得上的写作课 -〔涵柏〕

Tony Bai · Go语言第一课 -〔Tony Bai〕

PPT设计进阶 · 从基础操作到高级创意 -〔李金宝(Bobbie)〕

AI 应用实战课 -〔黄佳〕

好记忆不如烂笔头。留下您的足迹吧 :)