In my last post I documented the basics of Flutter and some of the common Widgets. This post is mainly about some of the common layouts of Flutter.

The index The article
1 Write an open Source Chinese Client based on Flutter from 0 (1)

Flutter build | nuggets technical essay introduction and development environment
2 Write an open Source Chinese Client based on Flutter from 0 (2)

Dart Grammar Basics
3 Write an open Source Chinese Client based on Flutter from 0 (3)

Introduction to Flutter & Common Widgets
👉 4 Write an open Source Chinese Client based on Flutter from 0 (4)

Foundation of Flutter layout
5 Write an open Source Chinese Client based on Flutter from 0 (5)

Set up the overall layout framework of the App
6 Write an open Source Chinese Client based on Flutter from 0 (6)

Implementation of various static pages
7 Write an open Source Chinese Client based on Flutter from 0 (7)

App network requests and data stores
8 Write an open Source Chinese Client based on Flutter from 0 (8)

Use of plug-ins

Fluted container

In Android development, we use XML files to write layouts, LinearLayout, RelativeLayout, ConstraintLayout, etc. In ReactNative or WEEX development, The layout we use is based on the front end Flex layout. Whether it’s Android or RN or WEEX, the layout feature is that the code is separate from the layout. With Flutter, the layout is a little bit different because the logic code and the layout code are written together, using Dart.

When we talk about layouts, we have to talk about containers. Whether we’re using native or cross-platform mobile development methods like RN and WEEX, layouts involve containers. For example, in native Android development, LinearLayout is a layout, which is also a container that can contain multiple sub-components. It is also a container that can contain multiple child components. In WEEX development,

is also a container that can contain multiple child components.

Layout containers in Flutter fall into two main categories: layout containers that can contain only one child Widget and containers that can contain multiple child widgets, whose usage is described below.

A layout container that contains a single child Widget

Center component

The child components in the Center component are centered. The Center component will be as large as possible if you don’t set any constraints on it. Here is how to use the Center component:

import 'package:flutter/material.dart';

main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "Test",
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Test")
        ),
        body: new Center(
          child: new Text("hello world")))); }}Copy the code

The Container components

Container is a layout Container that uses a large number of layouts. There are several rules for displaying containers:

  1. If there are no child components in the Container, the Container will be as large as possible
  2. If a Container has child components, the Container ADAPTS to the size of the child components
  3. If the size of a Container is set, the Container is displayed according to the size
  4. Container display rules are not only related to its own constraints and child components, but also to its parent components

The following code shows how Container can be used:

import 'package:flutter/material.dart';

main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "Test",
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Test"), body: new Container(width: 100.0, height: 100.0, color: color.red, Child: new Text(width: 100.0, height: 100.0, Color: color.red, Child: new Text("Flutter!")))); }}Copy the code

If we comment out the width/ Height and child properties in the Container code above, the interface will look different:

Container can also set the margins and margins, as shown in the following code:

Margin: const EdgeInsets. All (20.0), // Set the padding to each of the 4 edges: Const EdgeInsets. FromLTRB (10.0, 20.0, 30.0, 40.0), width: 100.0, height: 100.0, color: color.red, Child: new Text("Flutter!"),Copy the code

Padding components

The Padding component is used to set the Padding for its children. It is simple to use:

New padding-in (padding-in: new edgeinset.all (8.0), child: const Card(child: const Text('Hello World! ')))Copy the code

Align the component

The Align component is used to place its children in a certain position. For example, the following code shows how to place the Text component in the bottom right corner of a 100*100 container:

New Container(width: 100.0, height: 100.0, color: color. red, child: new Align(Child: new Text("hello"),
    alignment: Alignment.bottomRight,
  ),
)
Copy the code

The Alignment class has the following static constants:

/// The top left corner. Static const Alignment topLeft = const Alignment(-1.0, -1.0); /// The center point along The top edge. Static const Alignment topCenter = const Alignment(0.0, -1.0); /// The top right corner. static const Alignment topRight = const Alignment(1.0, -1.0); /// The center point along The left edge. Static const Alignment centerLeft = const Alignment(-1.0, 0.0); This example demonstrates const Alignment center = const Alignment(0.0, 0.0); /// The center point, both horizontally and horizontally. /// The center point along The right edge. Static const Alignment centerRight = const Alignment(1.0, 0.0); /// The bottom left corner. Static const Alignment bottomLeft = const Alignment(-1.0, 1.0); /// The center point along The bottom edge. Static const Alignment bottom center = const Alignment(0.0, 1.0); /// The bottom right corner. Static const Alignment bottom right = const Alignment(1.0, 1.0);Copy the code

FittedBox components

The FittedBox component locates its children based on the Fit property, which is a value of type BoxFit. BoxFit is an enumeration class that has several values:

enum BoxFit {
  fill,
  contain,
  cover,
  fitWidth,
  fitHeight,
  none,
  scaleDown,
}
Copy the code

In my last blog post, I introduced these types of BoxFit when I talked about the Image component. Here’s some code and screenshots to illustrate the BoxFit types. In the code below, we put a Text in a 200*100 Container. Use FittedBox to control the different display states of Text:

New Container(width: 200.0, height: 100.0, color: color.red, Child: new FittedBox(Child: new Text("hello world"),
    fit: BoxFit.fill,
  )
)
Copy the code

When fit is different, the above code runs as shown in the figure below:

AspectRatio components

The AspectRatio component is used to have its children displayed in proportion. Here is an example code:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "Test",
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Test"), body: new AspectRatio(// Container component 16:9 (width/height) Colors.red, ), ) ), ); }}Copy the code

If aspectRatio is set to 1.0, Container is displayed as a square. (Note that/in Dart represents division, not rounding. Use ~/ to do the rounding.)

ConstrainedBox components

ConstrainedBox the ConstrainedBox component is used to impose constraints on its children, such as the following code:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "Test",
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Test"), body: new ConstrainedBox(constraints: const BoxConstraints. Expand (width: 50.0, height: 50.0), child: New Container(color: color.red, width: 200.0, height: 200.0,)),); }}Copy the code

In the code above, we set the width and length of the Container to 200, but the Container is wrapped by a ConstrainedBox component, which sets the constraints: Const BoxConstraints. Expand (width: 50.0, height: 50.0), ConstrainedBox is mandatory, so the Container displays size 50 instead of 200, as shown below:

IntrinsicWidth & IntrinsicHeight

The purpose of these two components is to adjust their children to the width/height of the component itself.

This class is useful, for example, when there is no limit to the width/height, and you want the child components to be displayed at a more reasonable width/height rather than an infinite extension.

LimitedBox components

LimitedBox is a container that is limited in size only if it is not itself constrained.

If the maximum width of the component is unconstrained, then its width is limited to maxWidth. Similarly, if the maximum height of this component is not constrained, then its height is limited to maxHeight.

Offstage components

The Offstage component is used to show or hide its children, as shown in the following code:

new Offstage(
  offstage: false, / /true: hide,false: Display child: new Text("hello world"),Copy the code

OverflowBox & SizedOverflowBox

OverflowBox component it imposes different constraints on its children than it does on its parent, possibly allowing the children to overflow into the parent.

The SizedOverflowBox component is a component of a specified size, and its constraints are passed to child components, which may overflow.

SizedBox components

A SizedBox is a container with a specified size.

If the SizedBox size is specified, the child component uses the SizedBox size. If the SizedBox size is not specified, the SizedBox uses the child component size. If the SizedBox does not have child components, the SizedBox will display its own size, using nulls as zeros.

New SizedBox(// If width and height are specified, then the Container displays the specified size, not the Container's own size. If width and height are not specified, Width: 50.0, height: 50.0, child: new Container(color: color.red, width: 300.0, height: 50.0) 300.0,),)Copy the code

The Transform component

Transform is used to perform some transformation operations on a child component before drawing it, such as translation, rotation, scaling, and so on.

The example code is as follows:

New Container(color: color. black, Child: new Transform(alignment: alignment'dart:math'as math; Transform: new Matrix4 skewY (0.3.). RotateZ (-math.pi / 12.0), Child: New Container(padding: const edgeinset.all (8.0), color: const Color(0xFFE8581C), child: const Text('Apartment for rent! '),),),)Copy the code

The running effect is as follows:

A layout container containing multiple child widgets

The Row components

The Row component literally represents a Row, and multiple child components can be placed within a Row.

Here is the sample code:

import 'package:flutter/material.dart';

main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "Test",
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Test")
        ),
        body: new Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text("hello"), new Container(width: 50.0, height: 50.0, color: color.red,), new Text(width: 50.0, height: 50.0, color: color.red,), new Text("world"() [] () [ }}Copy the code

Here’s what it looks like when it runs on the simulator:

In the constructor of the Row component, the children argument is an array indicating that there can be more than one child component. MainAxisAlignment indicates that the child component in the Row is in the main axis (Row indicates the horizontal axis, cross axis indicates the vertical axis, Column indicates the vertical axis, and Column indicates the vertical axis). The cross axis indicates the horizontal alignment. The value can be:

  • MainAxisAlignment.start
  • MainAxisAlignment.center
  • MainAxisAlignment.end
  • MainAxisAlignment.spaceBetween
  • MainAxisAlignment.spaceAround
  • MainAxisAlignment.spaceEvenly

The above values are illustrated by the following figures:

The Column component

The Column component represents a Column. Multiple components can be placed in a Column, as shown in the following code:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "Test",
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Test")
        ),
        body: new Column(
          children: <Widget>[
            new Text("hello"),
            new Text("world"),
            new Text("nihao~"() [] () [ }}Copy the code

As with the Row component, MainAxisAlignment or CrossAxisAlignment can be used to set the alignment of the main axis and cross axis, which is not covered here.

Stack components

The Stack component is similar to FrameLayout in Android, where the child components are stacked one on top of the other. Unlike the child components in Row or Column, they are arranged horizontally or vertically.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "Test",
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Test"), body: new Stack(children: <Widget>[new Container(width: 100.0, height: 100.0, color: Color.red,), new Container(width: 30.0, height: 30.0, color: color.green,)],),); }}Copy the code

In the Stack component above, put two containers. The first Container is 100×100 and the second is 30×30. The emulator runs the Container as follows:

IndexedStack components

IndexedStack is used to display sub-components by index. An index of 0 displays the first sub-component, an index of 1 displays the second sub-component, and so on.

New Container(width: 100.0, height: 100.0, color: color.red, child: new Center( child: new Text("index: 0", style: new TextStyle(width: 100.0, height: 100.0, color: color.green, child: new Center( child: new Text("index: 1", style: new TextStyle(fontSize: 20.0),),)],)Copy the code

The constructor of IndexedStack has an index attribute. If index is 1, it displays the second element in the children array (the green square). If index is 0, it displays the first element (the red square). If the size of index exceeds the length of the children array, an error will be reported.

The Table component

The Table component is used to display a multi-row, multi-column layout. If there is only one Row or Column, it is more efficient to use Row or Column. The following code shows the use of Table:

Class MyApp extends StatelessWidget {List<TableRow>getData() {
    var data = [
      "hello"."world"
    ];
    List<TableRow> result = new List<TableRow>();
    TextStyle style = new TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold);
    for (int i = 0; i < data.length; i++) {
      String str = data[i];
      List<Widget> row = new List();
      for (int j = 0; j < str.length; j++) {
        row.add(new Text(" ${str[j]} ", style: style));
      }
      result.add(new TableRow(
        children: row
      ));
    }
    return result;
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "Test",
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Test") ), body: new Table( children: getData() ) ), ); }}Copy the code

Running the above code in the emulator looks like this:

Wrap the component

The Wrap component can display its children in multiple lines, horizontal or vertical. Here is an example:

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "Test",
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Test"), body: new Wrap(spacing: 5.0, // spacing between two children: 20.0, // spacing between two children: <Widget>[new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"),
            new Text("hello"))))); }}Copy the code

The running effect on the simulator is as follows:

If you replace Wrap with Row in the above code, you will notice that the child components in the Row will not Wrap when they exceed the screen width.

ListView component

ListView is a very common component, on the mobile end, basically most pages need to use ListView to display data, about the basic use of ListView, has been recorded in the previous article.

Afterword.

If you have experience in mobile development, it should be easy to learn by analogy. Even if you are not familiar with Flutter, you can find the detailed usage by looking at the document. Thanks to the Official English translation of Flutter on The Chinese website. I also have a lot of references to the Chinese website Flutter. I hope everyone can learn, improve and have fun using Flutter!

My open source project

  1. Google Flutter based on the open source Chinese client, hope you give a Star support, source code:
  • GitHub
  • Yards cloud

  1. Tetris based on the Flutter small game, I hope you give a Star support, source:
  • GitHub
  • Yards cloud

In the previous The next article
Write an open Source Chinese Client based on Flutter from 0 (3)

— Introduction to Flutter & Common Widgets
Write an open source Chinese client (5) based on Flutter from 0 –

Set up the overall layout framework of the App