Flutter Layouts

 

The main concept of the layout mechanism is the widget. We know that flutter assume everything as a widget. So the image, icon, text, and even the layout of your app are all widgets. Here, some of the things you do not see on your app UI, such as rows, columns, and grids that arrange, constrain, and align the visible widgets are also the widgets.

Flutter allows us to create a layout by composing multiple widgets to build more complex widgets. For example, we can see the below image that shows three icons with a label under each one.

Flutter Layouts

In the second image, we can see the visual layout of the above image. This image shows a row of three columns, and these columns contain an icon and label.




In the above image, the container is a widget class that allows us to customize the child widget. It is mainly used to add borders, padding, margins, background color, and many more. Here, the text widget comes under the container for adding margins. The entire row is also placed in a container for adding margin and padding around the row. Also, the rest of the UI is controlled by properties such as color, text.style, etc.

Layout a widget

Let us learn how we can create and display a simple widget. The following steps show how to layout a widget:

Step 1: First, you need to select a Layout widget.

Step 2: Next, create a visible widget.

Step 3: Then, add the visible widget to the layout widget.

Step 4: Finally, add the layout widget to the page where you want to display.

Types of Layout Widgets

We can categories the layout widget into two types:

  1. Single Child Widget
  2. Multiple Child Widget

Single Child Widgets

The single child layout widget is a type of widget, which can have only one child widget inside the parent layout widget. These widgets can also contain special layout functionality. Flutter provides us many single child widgets to make the app UI attractive. If we use these widgets appropriately, it can save our time and makes the app code more readable. The list of different types of single child widgets are:

Container: It is the most popular layout widget that provides customizable options for painting, positioning, and sizing of widgets.

  1. Center(  
  2.   child: Container(  
  3.     margin: const EdgeInsets.all(15.0),  
  4.     color: Colors.blue,  
  5.     width: 42.0,  
  6.     height: 42.0,  
  7.   ),  
  8. )  

Padding: It is a widget that is used to arrange its child widget by the given padding. It contains EdgeInsets and EdgeInsets.fromLTRB for the desired side where you want to provide padding.

  1. const Greetings(  
  2.   child: Padding(  
  3.     padding: EdgeInsets.all(14.0),  
  4.     child: Text('Hello JavaTpoint!'),  
  5.   ),  
  6. )  

Center: This widget allows you to center the child widget within itself.

Align: It is a widget, which aligns its child widget within itself and sizes it based on the child's size. It provides more control to place the child widget in the exact position where you need it.

  1. Center(  
  2.   child: Container(  
  3.     height: 110.0,  
  4.     width: 110.0,  
  5.     color: Colors.blue,  
  6.     child: Align(  
  7.       alignment: Alignment.topLeft,  
  8.       child: FlutterLogo(  
  9.         size: 50,  
  10.       ),  
  11.     ),  
  12.   ),  
  13. )  

SizedBox: This widget allows you to give the specified size to the child widget through all screens.

  1. SizedBox(  
  2.   width: 300.0,  
  3.   height: 450.0,  
  4.   child: const Card(child: Text('Hello JavaTpoint!')),  
  5. )  

AspectRatio: This widget allows you to keep the size of the child widget to a specified aspect ratio.

  1. AspectRatio(  
  2.   aspectRatio: 5/3,  
  3.   child: Container(  
  4.     color: Colors.bluel,  
  5.   ),  
  6. ),  

Baseline: This widget shifts the child widget according to the child's baseline.

  1. child: Baseline(  
  2.          baseline: 30.0,  
  3.          baselineType: TextBaseline.alphabetic,  
  4.          child: Container(  
  5.               height: 60,  
  6.               width: 50,  
  7.               color: Colors.blue,  
  8.          ),  
  9. )  

ConstrainedBox: It is a widget that allows you to force the additional constraints on its child widget. It means you can force the child widget to have a specific constraint without changing the properties of the child widget.

  1. ConstrainedBox(  
  2.   constraints: new BoxConstraints(  
  3.     minHeight: 150.0,  
  4.     minWidth: 150.0,  
  5.     maxHeight: 300.0,  
  6.     maxWidth: 300.0,  
  7.   ),  
  8.   child: new DecoratedBox(  
  9.     decoration: new BoxDecoration(color: Colors.red),  
  10.   ),  
  11. ),  

CustomSingleChildLayout: It is a widget, which defers from the layout of the single child to a delegate. The delegate decides to position the child widget and also used to determine the size of the parent widget.

FittedBox: It scales and positions the child widget according to the specified fit.

  1. import 'package:flutter/material.dart';  
  2.   
  3. void main() => runApp(MyApp());  
  4.   
  5. class MyApp extends StatelessWidget {  
  6.   // It is the root widget of your application.  
  7.   @override  
  8.   Widget build(BuildContext context) {  
  9.     return MaterialApp(  
  10.       title: 'Multiple Layout Widget',  
  11.       debugShowCheckedModeBanner: false,  
  12.       theme: ThemeData(  
  13.         // This is the theme of your application.  
  14.         primarySwatch: Colors.green,  
  15.       ),  
  16.       home: MyHomePage(),  
  17.     );  
  18.   }  
  19. }  
  20. class MyHomePage extends StatelessWidget {  
  21.   
  22.   @override  
  23.   Widget build(BuildContext context) {  
  24.     return Scaffold(  
  25.         appBar: AppBar(title: Text("FittedBox Widget")),  
  26.         body: Center(  
  27.         child: FittedBox(child: Row(  
  28.           children: <Widget>[  
  29.             Container(  
  30.               child: Image.asset('assets/computer.png'),  
  31.               ),  
  32.               Container(  
  33.                 child: Text("This is a widget"),  
  34.               )  
  35.             ],  
  36.           ),  
  37.           fit: BoxFit.contain,  
  38.         )  
  39.       ),  
  40.     );  
  41.   }  
  42. }  

Output

Flutter Layouts

FractionallySizedBox: It is a widget that allows to sizes of its child widget according to the fraction of the available space.

IntrinsicHeight and IntrinsicWidth: They are a widget that allows us to sizes its child widget to the child's intrinsic height and width.

LimitedBox: This widget allows us to limits its size only when it is unconstrained.

Offstage: It is used to measure the dimensions of a widget without bringing it on to the screen.

OverflowBox: It is a widget, which allows for imposing different constraints on its child widget than it gets from a parent. In other words, it allows the child to overflow the parent widget.

Example

  1. import 'package:flutter/material.dart';  
  2.   
  3. void main() => runApp(MyApp());  
  4.   
  5. class MyApp extends StatelessWidget {  
  6.   // It is the root widget of your application.  
  7.   @override  
  8.   Widget build(BuildContext context) {  
  9.     return MaterialApp(  
  10.       title: 'Single Layout Widget',  
  11.       debugShowCheckedModeBanner: false,  
  12.       theme: ThemeData(  
  13.         // This is the theme of your application.  
  14.         primarySwatch: Colors.blue,  
  15.       ),  
  16.       home: MyHomePage(),  
  17.     );  
  18.   }  
  19. }  
  20. class MyHomePage extends StatelessWidget {  
  21.     
  22.   @override  
  23.   Widget build(BuildContext context) {  
  24.     return Scaffold(  
  25.       appBar: AppBar(  
  26.         title: Text("OverflowBox Widget"),  
  27.       ),  
  28.       body: Center(  
  29.       child: Container(  
  30.         height: 50.0,  
  31.         width: 50.0,  
  32.         color: Colors.red,  
  33.         child: OverflowBox(  
  34.           minHeight: 70.0,  
  35.           minWidth: 70.0,  
  36.           child: Container(  
  37.             height: 50.0,  
  38.             width: 50.0,  
  39.             color: Colors.blue,  
  40.             ),  
  41.           ),  
  42.         ),  
  43.       ),  
  44.     );  
  45.   }  
  46. }  

Output

Flutter Layouts

Multiple Child widgets

The multiple child widgets are a type of widget, which contains more than one child widget, and the layout of these widgets are unique. For example, Row widget laying out of its child widget in a horizontal direction, and Column widget laying out of its child widget in a vertical direction. If we combine the Row and Column widget, then it can build any level of the complex widget.

Here, we are going to learn different types of multiple child widgets:

Row: It allows to arrange its child widgets in a horizontal direction.

Example

  1. import 'package:flutter/material.dart';  
  2.   
  3. void main() => runApp(MyApp());  
  4.   
  5. class MyApp extends StatelessWidget {  
  6.   // It is the root widget of your application.  
  7.   @override  
  8.   Widget build(BuildContext context) {  
  9.     return MaterialApp(  
  10.       title: 'Multiple Layout Widget',  
  11.       debugShowCheckedModeBanner: false,  
  12.       theme: ThemeData(  
  13.         // This is the theme of your application.  
  14.         primarySwatch: Colors.blue,  
  15.       ),  
  16.       home: MyHomePage(),  
  17.     );  
  18.   }  
  19. }  
  20. class MyHomePage extends StatelessWidget {  
  21.   @override  
  22.   Widget build(BuildContext context) {  
  23.     return Center(  
  24.       child: Container(  
  25.         alignment: Alignment.center,  
  26.         color: Colors.white,  
  27.         child: Row(  
  28.           children: <Widget>[  
  29.             Expanded(  
  30.               child: Text('Peter', textAlign: TextAlign.center),  
  31.             ),  
  32.             Expanded(  
  33.               child: Text('John', textAlign: TextAlign.center ),  
  34.   
  35.             ),  
  36.             Expanded(  
  37.               child: FittedBox(  
  38.                 fit: BoxFit.contain, // otherwise the logo will be tiny  
  39.                 child: const FlutterLogo(),  
  40.               ),  
  41.             ),  
  42.           ],  
  43.         ),  
  44.       ),  
  45.     );  
  46.   }  
  47. }  

Output

Flutter Layouts

Column: It allows to arrange its child widgets in a vertical direction.

ListView: It is the most popular scrolling widget that allows us to arrange its child widgets one after another in scroll direction.

GridView: It allows us to arrange its child widgets as a scrollable, 2D array of widgets. It consists of a repeated pattern of cells arrayed in a horizontal and vertical layout.

Expanded: It allows to make the children of a Row and Column widget to occupy the maximum possible area.

Table: It is a widget that allows us to arrange its children in a table based widget.

Flow: It allows us to implements the flow-based widget.

Stack: It is an essential widget, which is mainly used for overlapping several children widgets. It allows you to put up the multiple layers onto the screen. The following example helps to understand it.

  1. import 'package:flutter/material.dart';  
  2.   
  3. void main() => runApp(MyApp());  
  4.   
  5. class MyApp extends StatelessWidget {  
  6.   // It is the root widget of your application.  
  7.   @override  
  8.   Widget build(BuildContext context) {  
  9.     return MaterialApp(  
  10.       title: 'Multiple Layout Widget',  
  11.       debugShowCheckedModeBanner: false,  
  12.       theme: ThemeData(  
  13.         // This is the theme of your application.  
  14.         primarySwatch: Colors.blue,  
  15.       ),  
  16.       home: MyHomePage(),  
  17.     );  
  18.   }  
  19. }  
  20. class MyHomePage extends StatelessWidget {  
  21.   @override  
  22.   Widget build(BuildContext context) {  
  23.     return Center(  
  24.       child: Container(  
  25.         alignment: Alignment.center,  
  26.         color: Colors.white,  
  27.         child: Stack(  
  28.           children: <Widget>[  
  29.             // Max Size  
  30.             Container(  
  31.               color: Colors.blue,  
  32.             ),  
  33.             Container(  
  34.               color: Colors.pink,  
  35.               height: 400.0,  
  36.               width: 300.0,  
  37.             ),  
  38.             Container(  
  39.               color: Colors.yellow,  
  40.               height: 220.0,  
  41.               width: 200.0,  
  42.             )  
  43.           ],  
  44.         ),  
  45.       ),  
  46.     );  
  47.   }  
  48. }  

Output

Flutter Layouts

Building Complex Layout

In this section, we are going to learn how you can create a complex user interface using both single and multiple child layout widgets. The layout framework allows you to create a complex user interface layout by nesting the rows and columns inside of rows and columns.

Let us see an example of a complex user interface by creating the product list. For this purpose, you need first to replace the code of main.dart file with the following code snippet.

  1. import 'package:flutter/material.dart';  
  2.   
  3. void main() => runApp(MyApp());  
  4.   
  5. class MyApp extends StatelessWidget {  
  6.   // It is the root widget of your application.  
  7.   @override  
  8.   Widget build(BuildContext context) {  
  9.     return MaterialApp(  
  10.       title: 'Flutter Demo Application', theme: ThemeData(  
  11.       primarySwatch: Colors.green,),  
  12.       home: MyHomePage(title: 'Complex layout example'),  
  13.     );  
  14.   }  
  15. }  
  16. class MyHomePage extends StatelessWidget {  
  17.   MyHomePage({Key key, this.title}) : super(key: key);  
  18.   final String title;  
  19.   
  20.   @override  
  21.   Widget build(BuildContext context) {  
  22.     return Scaffold(  
  23.         appBar: AppBar(title: Text("Product List")),  
  24.         body: ListView(  
  25.           padding: const EdgeInsets.fromLTRB(3.012.03.012.0),  
  26.           children: <Widget>[  
  27.             ProductBox(  
  28.                 name: "iPhone",  
  29.                 description: "iPhone is the top branded phone ever",  
  30.                 price: 55000,  
  31.                 image: "iphone.png"  
  32.             ),  
  33.             ProductBox(  
  34.                 name: "Android",  
  35.                 description: "Android is a very stylish phone",  
  36.                 price: 10000,  
  37.                 image: "android.png"  
  38.             ),  
  39.             ProductBox(  
  40.                 name: "Tablet",  
  41.                 description: "Tablet is a popular device for official meetings",  
  42.                 price: 25000,  
  43.                 image: "tablet.png"  
  44.             ),  
  45.             ProductBox(  
  46.                 name: "Laptop",  
  47.                 description: "Laptop is most famous electronic device",  
  48.                 price: 35000,  
  49.                 image: "laptop.png"  
  50.             ),  
  51.             ProductBox(  
  52.                 name: "Desktop",  
  53.                 description: "Desktop is most popular for regular use",  
  54.                 price: 10000,  
  55.                 image: "computer.png"  
  56.             ),  
  57.           ],  
  58.         )  
  59.     );  
  60.   }  
  61. }  
  62. class ProductBox extends StatelessWidget {  
  63.   ProductBox({Key key, this.name, this.description, this.price, this.image}) :  
  64.         super(key: key);  
  65.   final String name;  
  66.   final String description;  
  67.   final int price;  
  68.   final String image;  
  69.   
  70.   Widget build(BuildContext context) {  
  71.     return Container(  
  72.         padding: EdgeInsets.all(2),  
  73.         height: 110,  
  74.         child: Card(  
  75.             child: Row(  
  76.                 mainAxisAlignment: MainAxisAlignment.spaceEvenly,  
  77.                 children: <Widget>[  
  78.                   Image.asset("assets/" + image),  
  79.                   Expanded(  
  80.                       child: Container(  
  81.                           padding: EdgeInsets.all(5),  
  82.                           child: Column(  
  83.                             mainAxisAlignment: MainAxisAlignment.spaceEvenly,  
  84.                             children: <Widget>[  
  85.                               Text(  
  86.                                   this.name, style: TextStyle(  
  87.                                   fontWeight: FontWeight.bold  
  88.                               )  
  89.                               ),  
  90.                               Text(this.description), Text(  
  91.                                   "Price: " + this.price.toString()  
  92.                               ),  
  93.                             ],  
  94.                           )  
  95.                       )  
  96.                   )  
  97.                 ]  
  98.             )  
  99.         )  
  100.     );  
  101.   }  
  102. }  

In the above code, we create widget ProductBox that contains the details of the product, such as image, name, price, and description. In the ProductBox widget, we use the following child widgets: Container, Row, Column, Expanded, Card, Text, Image, etc. This widget contains the following layout:

Flutter Layouts

Output

Now, when we run the dart file in the android emulator, it will give the following output.

Flutter Layouts


Post a Comment

Previous Post Next Post