- Flutter Layout Cheat Sheet
- Tomek Polański
- The Nuggets translation Project
- Permanent link to this article: github.com/xitu/gold-m…
- Translator: EmilyQiRabbit
- Proofreader: Smilemuffie, Suhanyujie
Do you need to know a simple layout template for Flutter? Now I will show you a series of code snippets of the Flutter layout that I have summarized. I’ll try to keep the code short and easy to understand, and I’ll give you renderings. But we still need to do it step by step — the template catalog will follow. I will focus more on the application of Flutter components rather than simply displaying them (Flutter Gallery does this very well!). If you have other questions about Flutter layout, or would like to share your code with me, please leave a comment!
directory
- The Row and Column
- IntrinsicWidth and IntrinsicHeight
- Stack
- Expanded
- ConstrainedBox
- Container
- Decoration: BoxDecoration
- Image: DecorationImage
- Border: border
- BorderRadius: borderRadius
- Shape: BoxShape
- BoxShadow:
List<BoxShadow>
- Gradient: RadialGradient
- BackgroundBlendMode: BlendMode
- SizedBox
- SafeArea
The Row and Column
MainAxisAlignment
Row / * or * / Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),,),Copy the code
Row / * or * / Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),,),Copy the code
Row / * or * / Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),,),Copy the code
Row / * or * / Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),,),Copy the code
Row / * or * / Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),,),Copy the code
Row / * or * / Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),,),Copy the code
If you want to be different characters of baseline alignment, you should use CrossAxisAlignment. The baseline.
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: <Widget>[
Text(
'Baseline',
style: Theme.of(context).textTheme.display3,
),
Text(
'Baseline',
style: Theme.of(context).textTheme.body1,
),
],
),
Copy the code
CrossAxisAlignment
Row / * or * / Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 200),
Icon(Icons.star, size: 50),,),Copy the code
Row / * or * / Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 200),
Icon(Icons.star, size: 50),,),Copy the code
Row / * or * / Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 200),
Icon(Icons.star, size: 50),,),Copy the code
Row / * or * / Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 200),
Icon(Icons.star, size: 50),,),Copy the code
MainAxisSize
Row / * or * / Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),,),Copy the code
Row / * or * / Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),,),Copy the code
IntrinsicWidth and IntrinsicHeight
Want all parts in a row or column to be the same height/width as the tallest/widest part? Stop looking for it! Here’s the answer!
When you have this style of layout:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('IntrinsicWidth')),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
onPressed: () {},
child: Text('Short'),
),
RaisedButton(
onPressed: () {},
child: Text('A bit Longer'),
),
RaisedButton(
onPressed: () {},
child: Text('The Longest text button'),),),),); }Copy the code
But you want all buttons to be the width of the widest button, just use IntrinsicWidth: IntrinsicWidth
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('IntrinsicWidth')),
body: Center(
child: IntrinsicWidth(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
RaisedButton(
onPressed: () {},
child: Text('Short'),
),
RaisedButton(
onPressed: () {},
child: Text('A bit Longer'),
),
RaisedButton(
onPressed: () {},
child: Text('The Longest text button'),),),),),); }Copy the code
If you need to have all parts equal height to the highest part, use the combination IntrinsicHeight and Row.
Stack
Great for stacking parts together
@override
Widget build(BuildContext context) {
Widget main = Scaffold(
appBar: AppBar(title: Text('Stack')));return Stack(
fit: StackFit.expand,
children: <Widget>[
main,
Banner(
message: "Top Start",
location: BannerLocation.topStart,
),
Banner(
message: "Top End",
location: BannerLocation.topEnd,
),
Banner(
message: "Bottom Start",
location: BannerLocation.bottomStart,
),
Banner(
message: "Bottom End",
location: BannerLocation.bottomEnd,
),
],
);
}
Copy the code
If you want to use the pieces of your own, you would have to put them in the inside of the toy
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Stack')),
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Material(color: Colors.yellowAccent),
Positioned(
top: 0,
left: 0,
child: Icon(Icons.star, size: 50),
),
Positioned(
top: 340,
left: 250,
child: Icon(Icons.call, size: 50() [() [() [() }Copy the code
If you don’t want to guess the value of top or bottom, you can use LayoutBuilder to retrieve them
Widget build(BuildContext context) {
const iconSize = 50;
return Scaffold(
appBar: AppBar(title: Text('Stack with LayoutBuilder')),
body: LayoutBuilder(
builder: (context, constraints) =>
Stack(
fit: StackFit.expand,
children: <Widget>[
Material(color: Colors.yellowAccent),
Positioned(
top: 0,
child: Icon(Icons.star, size: iconSize),
),
Positioned(
top: constraints.maxHeight - iconSize,
left: constraints.maxWidth - iconSize,
child: Icon(Icons.call, size: iconSize),
),
],
),
),
);
}
Copy the code
Expanded
Expanded can be used with the Flex\Flexbox layout and is great for allocating multi-element Spaces.
Row(
children: <Widget>[
Expanded(
child: Container(
decoration: const BoxDecoration(color: Colors.red),
),
flex: 3,
),
Expanded(
child: Container(
decoration: const BoxDecoration(color: Colors.green),
),
flex: 2,
),
Expanded(
child: Container(
decoration: const BoxDecoration(color: Colors.blue),
),
flex: 1,),),Copy the code
ConstrainedBox
By default, most components use as little space as possible:
Card(child: const Text('Hello World! '), color: Colors.yellow)
Copy the code
ConstrainedBox enables the widget to use the desired free space.
ConstrainedBox(
constraints: BoxConstraints.expand(),
child: const Card(
child: const Text('Hello World! '),
color: Colors.yellow,
),
),
Copy the code
You can use BoxConstraints to specify how much space the widget can use — by specifying the min/ Max attributes of height/width.
BoxConstraints. Expand will make the component use unlimited (all available) space unless otherwise specified:
ConstrainedBox(
constraints: BoxConstraints.expand(height: 300),
child: const Card(
child: const Text('Hello World! '),
color: Colors.yellow,
),
),
Copy the code
The above code is equivalent to the following:
ConstrainedBox(
constraints: BoxConstraints(
minWidth: double.infinity,
maxWidth: double.infinity,
minHeight: 300,
maxHeight: 300,
),
child: const Card(
child: const Text('Hello World! '),
color: Colors.yellow,
),
),
Copy the code
Container
One of the most commonly used parts — and there’s a reason it’s so commonly used:
Container for the layout tool
If you do not specify the height and width of the Container, it will be the same size as the child
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Container as a layout')),
body: Container(
color: Colors.yellowAccent,
child: Text("Hi"),),); }Copy the code
If you want the Container to expand to equal its parent element, use double-.infinity for the height and width attributes
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Container as a layout')),
body: Container(
height: double.infinity,
width: double.infinity,
color: Colors.yellowAccent,
child: Text("Hi"),),); }Copy the code
The adornment of the Container
You can use the color property to change the background color of a Container, but decoration and foregroundDecoration can do more. (With these two properties, you can completely change the look of the Container, which I’ll discuss later because there’s a lot to cover.) Decorations are always placed after children, while foregrounddecorations are placed above them.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Container.decoration')),
body: Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(color: Colors.yellowAccent),
child: Text("Hi"),),); }Copy the code
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Container.foregroundDecoration')),
body: Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(color: Colors.yellowAccent),
foregroundDecoration: BoxDecoration(color: Colors.red.withOpacity(0.5)),
child: Text("Hi"),),); }Copy the code
The change of the Container
If you don’t want to use the Transform widget to change your layout, you can use the Transform property of the Container
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Container.transform')),
body: Container(
height: 300,
width: 300,
transform: Matrix4.rotationZ(pi / 4),
decoration: BoxDecoration(color: Colors.yellowAccent),
child: Text(
"Hi",
textAlign: TextAlign.center,
),
),
);
}
Copy the code
BoxDecoration
Decorator effects are usually used on container components to change the appearance of the component.
Image: DecorationImage
With the picture as the background:
Scaffold(
appBar: AppBar(title: Text('image: DecorationImage')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
color: Colors.yellow,
image: DecorationImage(
fit: BoxFit.fitWidth,
image: NetworkImage(
'https://flutter.io/images/catalog-widget-placeholder.png',),),),),),);Copy the code
Border: border
Specifies the container’s border style.
Scaffold(
appBar: AppBar(title: Text('border: Border')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
color: Colors.yellow,
border: Border.all(color: Colors.black, width: 3(), ((), ((), ((), ((), (()Copy the code
BorderRadius: borderRadius
Let the border be rounded.
If decoratedshape
是 BoxShape.circle
, thenborderRadius
Will be invalid
Scaffold(
appBar: AppBar(title: Text('borderRadius: BorderRadius')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
color: Colors.yellow,
border: Border.all(color: Colors.black, width: 3),
borderRadius: BorderRadius.all(Radius.circular(18))),),),);Copy the code
Shape: BoxShape
Boxes can be rectangular, square, oval or round in shape.
For any other shape, you should useShapeDecoration
Rather thanBoxDecoration
Scaffold(
appBar: AppBar(title: Text('shape: BoxShape')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
color: Colors.yellow,
shape: BoxShape.circle,
),
),
),
);
Copy the code
BoxShadow:List<BoxShadow>
You can add a shadow to the container.
This parameter is a list so that you can define many different shadows and then combine them together.
Scaffold(
appBar: AppBar(title: Text('boxShadow: List<BoxShadow>')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
color: Colors.yellow,
boxShadow: const [
BoxShadow(blurRadius: 10),],),),),);Copy the code
Gradient
There are three types of gradients: LinearGradient, RadialGradient, and SweepGradient.
Scaffold(
appBar: AppBar(title: Text('gradient: LinearGradient')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: const [
Colors.red,
Colors.blue,
],
),
),
),
),
);
Copy the code
Scaffold(
appBar: AppBar(title: Text('gradient: RadialGradient')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
gradient: RadialGradient(
colors: const [Colors.yellow, Colors.blue],
stops: const [0.4.1.0],),),),),);Copy the code
Scaffold(
appBar: AppBar(title: Text('gradient: SweepGradient')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
gradient: SweepGradient(
colors: const [
Colors.blue,
Colors.green,
Colors.yellow,
Colors.red,
Colors.blue,
],
stops: const [0.0.0.25.0.5.0.75.1.0],),),),),);Copy the code
backgroundBlendMode
BackgroundBlendMode is the most complex property in the BoxDecoration. It can mix the colors and gradients of the BoxDecoration, regardless of which element it is on.
With backgroundBlendMode, you can use a long list of algorithms in the BlendMode enumeration type.
First, configure the BoxDecoration as the foregroundDecoration, which is rendered above the child element of the Container (while the decoration is rendered after the child element).
Scaffold(
appBar: AppBar(title: Text('backgroundBlendMode')),
body: Center(
child: Container(
height: 200,
width: 200,
foregroundDecoration: BoxDecoration(
backgroundBlendMode: BlendMode.exclusion,
gradient: LinearGradient(
colors: const [
Colors.red,
Colors.blue,
],
),
),
child: Image.network(
'https://flutter.io/images/catalog-widget-placeholder.png'(), (), (), ();Copy the code
BackgroundBlendMode affects more than just the Container in which it resides.
BackgroundBlendMode can change the color of any part in the part tree of a Container. In this code, we have a parent Container that renders an image image and a child Container that uses backgroundBlendMode. You will still get the same effect as the previous code.
Scaffold(
appBar: AppBar(title: Text('backgroundBlendMode')),
body: Center(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://flutter.io/images/catalog-widget-placeholder.png',
),
),
),
child: Container(
height: 200,
width: 200,
foregroundDecoration: BoxDecoration(
backgroundBlendMode: BlendMode.exclusion,
gradient: LinearGradient(
colors: const [
Colors.red,
Colors.blue,
],
),
),
),
),
),
);
Copy the code
SizedBox
This is the simplest but most useful component
SizedBox for ConstrainedBox
SizedBox can achieve a similar effect to ConstrainedBox
SizedBox.expand(
child: Card(
child: Text('Hello World! '),
color: Colors.yellowAccent,
),
),
Copy the code
A SizedBox used as an inside margin
If you need to add Padding or margins, you can use the Padding or Container widget. But none of them are as easy to read as adding a Sizedbox
Column(
children: <Widget>[
Icon(Icons.star, size: 50),
const SizedBox(height: 100),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),,),Copy the code
A SizedBox used as an invisible object
Most of the time you want to control the display and hide of components with a Boolean value (bool)
Widget build(BuildContext context) {
bool isVisible = ...
return Scaffold(
appBar: AppBar(
title: Text('isVisible = $isVisible'),
),
body: isVisible
? Icon(Icons.star, size: 150)
: const SizedBox(),
);
}
Copy the code
Since SizedBox has a const constructor, using const SizedBox() is very simple.
A simpler solution is to use the Opacity widget and change the value to 0.0. The disadvantage of this solution is that although the component is not visible, it still takes up space.
SafeArea
On different platforms, there are many specific locations, like the Android status bar or the iPhone X’s “bangs,” that should be avoided.
The solution is to use SafeArea parts (the following examples are with and without SafeArea)
Widget build(BuildContext context) {
return Material(
color: Colors.blue,
child: SafeArea(
child: SizedBox.expand(
child: Card(color: Colors.yellowAccent),
),
),
);
}
Copy the code
Stay tuned for more
If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.
The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.