Flutter Course: 11.2 Layout Composition

Flutter is a powerful framework that allows you to easily create attractive User Interfaces (UI). In this lesson 11.2, we will delve deeply into the layout composition in Flutter. Layout composition is a crucial process for effectively placing complex UI elements. In this process, we will utilize various widgets and the layout system provided by Flutter.

1. Fundamental Concepts of Layout

Layout refers to the topic of how UI elements are arranged on the screen. Flutter uses widgets to compose layouts. Everything in Flutter is made up of widgets, and these widgets combine to form complex UIs. The layout system primarily uses containers, so the properties of the container determine the position of the UI.

1.1. Concept of Widgets

In Flutter, widgets are the components of the UI, and each widget has its own properties and layout. Flutter’s widgets are broadly categorized into StatelessWidget and StatefulWidget. StatelessWidget does not have a state and is used to create unchanging UIs. Conversely, StatefulWidget has a state and changes the UI according to state changes.

1.2. Parent-Child Relationship

Widgets have a parent-child relationship. A parent widget can include child widgets, enabling layout composition. For example, the Column widget can arrange multiple child widgets vertically.

2. Layout Widgets in Flutter

Flutter provides various layout widgets. In this section, we will look at the key layout widgets that are commonly used.

2.1. Container

The Container widget is the most basic widget and allows you to encapsulate other widgets to adjust size, padding, margins, etc. You can apply additional styles such as background color and borders using the Container.

Container(
  width: 200,
  height: 100,
  color: Colors.blue,
  padding: EdgeInsets.all(10),
  child: Text('Hello, Flutter!'),
)

2.2. Row

The Row widget arranges child widgets horizontally. You can define alignment methods using the mainAxisAlignment and crossAxisAlignment properties.

Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    Icon(Icons.star),
    Icon(Icons.star),
    Icon(Icons.star),
  ],
)

2.3. Column

The Column widget lists child widgets vertically. Similarly, you can adjust arrangements through mainAxisAlignment and crossAxisAlignment.

Column(
  mainAxisAlignment: MainAxisAlignment.start,
  children: [
    Text('Item 1'),
    Text('Item 2'),
    Text('Item 3'),
  ],
)

2.4. Stack

The Stack widget stacks multiple widgets on top of each other. You can adjust the position of each child widget using the Positioned widget.

Stack(
  children: [
    Container(color: Colors.red, width: 100, height: 100),
    Positioned(
      left: 20,
      top: 20,
      child: Container(color: Colors.blue, width: 50, height: 50),
    ),
  ],
)

2.5. ListView

The ListView widget creates a scrollable list. It is very useful for easily listing multiple items.

ListView(
  children: [
    ListTile(title: Text('Item 1')),
    ListTile(title: Text('Item 2')),
    ListTile(title: Text('Item 3')),
  ],
)

3. Layout Properties

We will learn about the main properties that can be used when configuring layout widgets.

3.1. Padding

You can use the Padding widget to add padding to a widget, setting space around child widgets.

Padding(
  padding: EdgeInsets.all(16.0),
  child: Text('Hello, Flutter!'),
)

3.2. Margin

Margins can be set as properties of the Container widget. This property expands the space around the child widget.

Container(
  margin: EdgeInsets.all(20),
  child: Text('Hello with Margin!'),
)

4. Composing Complex Layouts

Now, let’s create more complex layouts from simple widget compositions. We will combine multiple widgets to form a more realistic UI.

4.1. Creating a Card Layout

Let’s create a simple layout displaying information using a card. We will combine various widgets to create a UI that includes all elements.

Card(
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Padding(
        padding: const EdgeInsets.all(16.0),
        child: Text('Title', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
      ),
      Padding(
        padding: const EdgeInsets.all(16.0),
        child: Text('This is a sample card in Flutter.', style: TextStyle(fontSize: 16)),
      ),
      ButtonBar(
        children: [
          TextButton(child: Text('EDIT'), onPressed: () {/*Edit logic*/}),
          TextButton(child: Text('DELETE'), onPressed: () {/*Delete logic*/}),
        ],
      ),
    ],
  ),
)

5. Composing Responsive Layouts

It is also essential to create responsive layouts to allow users to use the application on various screen sizes.

5.1. Using MediaQuery

In Flutter, you can use MediaQuery to dynamically detect the size of the screen. This allows you to apply designs suitable for various screen sizes.

final width = MediaQuery.of(context).size.width;
final height = MediaQuery.of(context).size.height;

5.2. LayoutBuilder

The LayoutBuilder widget receives specific constraints for the child widget. Through this, you can configure it to act differently based on the widget’s size.

LayoutBuilder(
  builder: (BuildContext context, BoxConstraints constraints) {
    return Container(
      width: constraints.maxWidth < 600 ? 100 : 200,
      height: 100,
      child: Text('Responsive Container'),
    );
  },
)

6. Conclusion

In this lesson, we learned about layout composition in Flutter. We saw how to create complex UIs using various widgets and how responsive design can enhance user experience. By understanding and utilizing the layout system, we can develop better applications.