Flutter : The battle of containers!
Flutter is a framework for creating fast and beautiful UI for mobile, web and desktop. Wherever you read about flutter you will see that its all about widgets. Flutter have a lot of widgets in his pockets, some are used in almost every project and others are less common. The Container widget is one of the most used widgets because it can be used in so many situations. It can be compared to the DIV tag in HTML and CSS but with a lot more options. Indeed, it provides many functionalities for painting, positioning, and sizing widgets.
In this article we will take a look at some properties of the container widget. You can follow with me and try all the examples in this article in the online DartPad flutter editor.
The containers behavior
There are some rules that you must understand when using containers. For example, if a container has no children, it will try to be as big as possible inside its parent unless this parent provides unbounded constraints, in which case the container tries to size as small as possible. Containers with children size themselves to their children.
In the screenshot below we have a container with no child and the parent is the Center widget:
In this case the container will try to be as big as possible inside its parent while taking into consideration the margins applied to it.
Next, we will add a Text widget as a child.
Now, the container sizes itself to the child while, this time, taking into consideration the padding applied to it.
You can also give the container a fixed width or height or both.
Adding spices to containers: The BoxDecoration
The BoxDecoration class provides a variety of ways to draw a box inside a container. You can use it to specify borders, body shapes, and shadows and many other use cases. Use the borderRadius property to set the roundness of the corners.
First, we will add different colors and width to our container’s top, left, right and bottom borders. Note that when using decoration you must specify the color of the container inside the decoration property.
Next, we will change the borders style and add rounded corners to the container.
You can also control the shape of the container using the shape property:
Now, what about shadows? Very easy, just use the boxShadow property of the BoxDecoration :
Alignment
You must have noticed that in the shape example the text is not well aligned in the container. For that purpose we have the “alignment” property.
Stacking containers
If you want to overlap several children (containers for example) you can use the Stack widget.
Here is an example :
Note the use of the alignment property of the container, this time with values of the x and y positions (for the center: x=0 and y=0).
You can also use the Positioned widget inside the Stack widget to have a more accurate positioning of the children.
I am a button!!!
Flutter has many button widgets but sometimes you want to create a custom button of your own style. You can do that by wrapping your containers inside the GestureDetector widget like in the following example:
Clipping, clipping !
I you ever want to give your container a custom shape, you can use the ClipPath widget as a more advanced solution. This widget clips its child using a path. So all you have to do is wrapping your container with the ClipPath widget, create a path and apply it to the clipper property.
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'The battle of containers',
debugShowCheckedModeBanner: false,
home: Home(title: 'The battle of containers'),
);
}
}class Home extends StatefulWidget {
Home({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHome createState() => _MyHome();
}class _MyHome extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
widget.title,
style: TextStyle(color: Colors.white),
),
),
body: Padding(
padding: const EdgeInsets.all(40.0),
child: ClipPath(
child: Container(
width: MediaQuery.of(context).size.width,
height: 200,
alignment:Alignment.center,
color: Colors.blue,
),
clipper: CustomPath(),
),
),
);
}
}class CustomPath extends CustomClipper<Path> {
final arcHeight = 100.0;
final radius = 20.0;
@override
Path getClip(Size size) {
final path = Path();
path.lineTo(size.width, 0.0);
path.lineTo(size.width, size.height);
path.arcToPoint(Offset(size.width, size.height - arcHeight),
radius: Radius.circular(radius));
path.lineTo(size.width, size.height - arcHeight / 2);
path.lineTo(0, size.height - arcHeight / 2);
path.lineTo(0,size.height- arcHeight);
path.arcToPoint(Offset(0, size.height),
radius: Radius.circular(radius));path.close();
return path;
}@override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
You can find the source code of these examples here.
See also :