Welcome to follow the official wechat account: FSA Full stack action 👋
Monad layout widgets
A monad layout, as the name suggests, is a widget that contains only one child control
1, the Align (Center)
Center can Center the child control, and by default will stretch as far as possible to fill the parent control:
class CenterDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
returnCenter( child: Icon(Icons.pets), ); }}Copy the code
You can see from the Center source that Center is essentially an alignment that cannot be specified:
class Center extends Align {
/// Creates a widget that centers its child.
const Center({ Key? key, double? widthFactor, double? heightFactor, Widget? child })
: super(key: key, widthFactor: widthFactor, heightFactor: heightFactor, child: child);
}
class Align extends SingleChildRenderObjectWidget {
/// Creates an alignment widget.
///
/// The alignment defaults to [Alignment.center].
const Align({
Key? key,
this.alignment = Alignment.center,
this.widthFactor,
this.heightFactor,
Widget? child,
}) : assert(alignment ! =null),
assert(widthFactor == null || widthFactor >= 0.0),
assert(heightFactor == null || heightFactor >= 0.0),
super(key: key, child: child);
Copy the code
Therefore, it is perfectly acceptable to use Align instead of Center:
- WidthFactor: Specifies that the width of Align is several times the width of the child control
- HeightFactor: Specifies that the height of Align is several times the height of the child control
- alignment :
- Alignment. BottomCenter: The bottom is in the middle
- Alignment. Center: a center
- Alignment(x, Y) : The upper left corner is (-1, -1) and the lower right corner is (1, 1)
class AlignDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Center is the alignment with Center
// return Center(
// child: Icon(Icons.pets),
// );
return Align(
widthFactor: 5.// The width is 5 times the width of the child
heightFactor: 5.// The height is 5 times the height of the childalignment: Alignment.center, child: Icon(Icons.pets), ); }}Copy the code
In general, you specify the exact width value directly in the outer Container instead of using widthFactor
2, Padding
Normal widgets do not have a padding property (except Container). If you want to have a padding effect on the child Widget, you can apply a layer of padding to the child Widget. The padding has only two attributes. The padding attribute corresponds to an object of type EdgeInsetsGeometry, which is used in conjunction with the EdgeInsets constant name constructor:
- Padding: span
- EdgeInsets. All (8.0): Specifies the internal spacing uniformly
- EdgeInsets. Symmetric (Horizontal: 8, vertical: 8): The symmetric(horizontal: 8) is separated by a specified internal spacing
- EdgeInsets. FromLTRB (8, 8, 8, 8): Up, down, left, right, and left separated by specified inner spacing
- EdgeInsets. Only (left: 8): specifies the spacing in only one direction
class PaddingDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.all(8.0),
child: item("hello lqr"),
),
Divider(height: 1, color: Colors.black),
Padding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: item("hello gitlqr"),
),
Divider(height: 1, color: Colors.black),
Padding(
padding: EdgeInsets.fromLTRB(8.8.8.8),
child: item("hello charylin"),
),
Divider(height: 1, color: Colors.black),
Padding(
padding: EdgeInsets.only(left: 8),
child: item("hello charylin"),
),
Divider(height: 1, color: Colors.black),
],
);
}
Widget item(String content) {
return Text(
content,
style: TextStyle(
fontSize: 30, backgroundColor: Colors.red, color: Colors.white, ), ); }}Copy the code
3, the Container
Container is the most special widget in a Flutter. It can specify dimensions, internal and external spacing, 2D conversion, and so on:
- Width: the width of the
- Height: height
- Alignment: Alignment of child widgets
- Padding: Inner spacing, type EdgeInsetsGeometry, generally using subclass EdgeInsets
- Margin: outer spacing, type of EdgeInsetsGeometry, generally using the subclass EdgeInsets
- Transform: 2D transform, Matrix4 type
- Color: background color (note: it conflicts with the color in the decoration, only one setting can be selected)
- decoration:BoxDecoration()
- Color: background color
- Border: border style, type BoxBorder, commonly used
Border.all(width: 5)
To specify the - BorderRadius: borderRadius geometry type, often used
BorderRadius.circular(8)
To specify the - boxShadow:BoxShadow()
- Color: Shadow color
- Offset: indicates the shadow offset
- “SpreadRadius” : extends x and y on the basis of offset
class ContainerDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
// width and height are not specified
width: 200,
height: 200,
child: Icon(Icons.pets, size: 50, color: Colors.white),
// The location of the child element
alignment: Alignment.topLeft,
padding: EdgeInsets.all(20),
margin: EdgeInsets.all(10),
// Rotate 5 degrees to reduce by half
transform: Matrix4.rotationZ(degree2Radia(5)).scaled(0.5),
color: Colors.red,
),
Container(
width: 200,
height: 200,
child: Icon(Icons.accessibility, size: 50, color: Colors.white),
// Color conflicts with decoration
// color: Colors.red,
decoration: BoxDecoration(
color: Colors.red, / / the background color
border: Border.all(width: 5, color: Colors.blueAccent), / / frame
borderRadius: BorderRadius.circular(8), / / the rounded
boxShadow: [
BoxShadow(
color: Colors.blueGrey, // Shadow color
offset: Offset(10.10), // Shadow offset
spreadRadius: 5.// extend, equivalent to offset 15,15() [() [() [() }double degree2Radia(double degree) {
return degree * pi / 180; }}Copy the code
Multiple sub-layout widgets
A multichild layout, as its name implies, is a widget that can contain only multiple child controls
1, Flex
Flex in Flutter is similar to the Flex layout in CSS. It can control the placement of internal child widgets flexibly, but it is not used directly. Instead, it subclasses Row/Column:
- Row/Column inherits from Flex
- Row = Flex(direction: Axis.horizontal)
- MainAxis: Horizontal to the right
- CrossAxis: straight down
- Column = Flex(direction: Axis.vertical)
- MainAxis: Straight down
- CrossAxis: horizontal to the right
By default, Row takes up as much space horizontally as possible because its mainAxisSize property defaults to mainAxissize.max:
Column and Row are basically the same except in different directions. Therefore, Column will learn about Row as well
class ButtonRowDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
/// The Row features:
/// -Take up as much space as possible horizontally
/// *If you want to wrap content horizontally, you can set mainAxisSize = min
/// -Wrap content in the vertical direction
return Column(
children: [
RaisedButton(
child: Row(
children: [Icon(Icons.bug_report), Text("Bug report (MainAxisSize. Max)")],
),
onPressed: () {},
),
RaisedButton(
child: Row(
mainAxisSize: MainAxisSize.min, // Package contents. The package is Max full parent widget
children: [Icon(Icons.bug_report), Text("Bug report (MainAxisSize. Min)")], ), onPressed: () {}, ), ], ); }}Copy the code
2, Row
Row focuses on spindle and cross axis alignment:
- MainAxisAlignment:
- Start: Place elements one by one at the beginning of the spindle
- End: The end position of the spindle places the elements one by one
- Center: aligns the center point of the spindle
- SpaceBetween: the spaceBetween the left and right sides is 0, and the other elements are bisected between each other
- SpaceAround: The space between the left and right is half the space between the other elements
- Spaceinstituted: All spacing evenly divides space
- CrossAxisAlignment:
- Start: aligns the starting position of the cross axis
- End: Align the end position of the cross axis
- Center: Center point alignment (default)
- Baseline: baseline alignment (must have text)
- TextBaseline must be specified to use baseline alignment, otherwise an error will be reported.
- Stretch: Make the Row occupy as much space as possible on the cross axis, and stretch the height of the cross axis of all child widgets to the maximum
class RowDemo1 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
itemRow("start", MainAxisAlignment.start, "center", CrossAxisAlignment.center),
itemRow("end", MainAxisAlignment.end, "center", CrossAxisAlignment.center),
itemRow("center", MainAxisAlignment.center, "center", CrossAxisAlignment.center),
itemRow("spaceBetween", MainAxisAlignment.spaceBetween, "center", CrossAxisAlignment.center),
itemRow("spaceAround", MainAxisAlignment.spaceAround, "center", CrossAxisAlignment.center),
itemRow("spaceEvenly", MainAxisAlignment.spaceEvenly, "center", CrossAxisAlignment.center),
],
);
}
Widget itemRow(
String mainAxisAlignmentStr,
MainAxisAlignment mainAxisAlignment,
String crossAxisAlignmentStr,
CrossAxisAlignment crossAxisAlignment) {
return Container(
height: 120,
margin: const EdgeInsets.only(bottom: 8.0),
color: Colors.pink[100],
child: Stack(
fit: StackFit.expand,
children: [
Row(
mainAxisAlignment: mainAxisAlignment,
crossAxisAlignment: crossAxisAlignment,
TextDirection: textDirection. LTR, // RTL: typeset from right to left; LTR: Left-to-right layout (default)
children: [
Container(width: 80, height: 60, color: Colors.red),
Container(width: 120, height: 100, color: Colors.green),
Container(width: 90, height: 80, color: Colors.blue),
Container(width: 50, height: 120, color: Colors.orange),
],
),
Positioned(
left: 0,
bottom: 0,
child: Text(
"GitLqr >>> main:$mainAxisAlignmentStr , cross:$crossAxisAlignmentStr",
style: TextStyle(fontSize: 20, backgroundColor: Colors.black54, color: Colors.white), ), ) ], ), ); }}Copy the code
class RowDemo2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Baseline alignment
return Column(
children: [
itemRow("spaceEvenly", MainAxisAlignment.spaceEvenly, "start", CrossAxisAlignment.start),
itemRow("spaceEvenly", MainAxisAlignment.spaceEvenly, "center", CrossAxisAlignment.center),
itemRow("spaceEvenly", MainAxisAlignment.spaceEvenly, "end", CrossAxisAlignment.end),
itemRow("spaceEvenly", MainAxisAlignment.spaceEvenly, "stretch", CrossAxisAlignment.stretch),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.baseline,
// Alphabetic and ideographic baselines are almost the same
textBaseline: TextBaseline.ideographic,
children: [
Container(width: 80,height: 60, color: Colors.red, child: Text("Hellxo", style: TextStyle(fontSize: 20))),
Container(width: 120, height: 100, color: Colors.green, child: Text("Woxrld", style: TextStyle(fontSize: 30)),),
Container(width: 90, height: 80, color: Colors.blue, child: Text("abxc", style: TextStyle(fontSize: 12))),
Container(width: 50, height: 120, color: Colors.orange, child: Text("cxba", style: TextStyle(fontSize: 40[, [, [, [, [, [ } Widget itemRow(String mainAxisAlignmentStr,
MainAxisAlignment mainAxisAlignment,
String crossAxisAlignmentStr,
CrossAxisAlignment crossAxisAlignment) {
return Container(
height: 140,
margin: const EdgeInsets.only(bottom: 8.0),
color: Colors.pink[100],
child: Stack(
fit: StackFit.expand,
children: [
Row(
mainAxisAlignment: mainAxisAlignment,
crossAxisAlignment: crossAxisAlignment,
TextDirection: textDirection. LTR, // RTL: typeset from right to left; LTR: Left-to-right layout (default)
children: [
Container(width: 80, height: 60, color: Colors.red),
Container(width: 120, height: 100, color: Colors.green),
Container(width: 90, height: 80, color: Colors.blue),
Container(width: 50, height: 120, color: Colors.orange),
],
),
Positioned(
left: 0,
bottom: 0,
child: Text(
"GitLqr >>> main:$mainAxisAlignmentStr , cross:$crossAxisAlignmentStr",
style: TextStyle(fontSize: 20, backgroundColor: Colors.black54, color: Colors.white), ), ) ], ), ); }}Copy the code
The effect of the final group is CrossAxisAlignment. The baseline, you can see no matter how much text, at the bottom of the letter “x” are in a line, this is the baseline alignment. It is important to note that use CrossAxisAlignment. Baseline must specify both baseline textBaseline (the default value is null), Its value TextBaseline. Ideographic is almost the same as TextBaseline. Alphabetic
3, the Column
Column and Row both inherit from Flex and are almost identical except for the orientation differences. Here are just a few of the formatting differences:
- Row: indicates the typesetting direction TextDirection
- RTL: Typeset from right to left
- LTR: Left-to-right layout (default)
- Column: VerticalDirection
- Up: Typesetting from bottom to top
- Down: Typesetting from top to bottom (default)
class ColumnDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
verticalDirection: VerticalDirection.down,
// up: from bottom to top; Down: Typesetting from top to bottom (default)
children: [
Container(width: 80, height: 60, color: Colors.red),
Container(width: 120, height: 100, color: Colors.green),
Container(width: 90, height: 80, color: Colors.blue),
Container(width: 50, height: 120, color: Colors.orange),
Text(
"GitLqr >>> VerticalDirection.down",
style: TextStyle(fontSize: 20, backgroundColor: Colors.black54, color: Colors.white),
),
],
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
verticalDirection: VerticalDirection.up,
// up: from bottom to top; Down: Typesetting from top to bottom (default)
children: [
Container(width: 80, height: 60, color: Colors.red),
Container(width: 120, height: 100, color: Colors.green),
Container(width: 90, height: 80, color: Colors.blue),
Container(width: 50, height: 120, color: Colors.orange),
Text(
"GitLqr >>> VerticalDirection.up",
style: TextStyle(fontSize: 20, backgroundColor: Colors.black54, color: Colors.white), ), ], ), ), ]); }}Copy the code
4, Flexible (Expanded)
-
Attribute in Flexible:
- Fit: Fill mode
- Tight: The child control forces the available space to be filled
- Loose: The child control only occupies its own size
- Flex: This works when fit is tight
- When flex is not specified: Stretch Flexible equally until the available space is filled, equivalent to 1 flex
- When Flex is specified: Stretch Flexible in flex proportions until the available space is filled, at which point the original width is invalid
- Fit: Fill mode
-
Expanded = Flexible(fit: FlexFit.tight)
- Stretch the child control when Flex(Row/Column) has space available
- Shrink the child control when it exceeds Flex(Row/Column) space
class ExpandedDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
item1(),
tip("Flexible fit: FlexFit.tight flex: 1"),
item2(),
tip("Expanded flex: 1 , flex: 1 (width: 120)"),
item3(),
tip("Expanded flex: 1 , flex: 2 (width: 10000)"),]); } Widget item1() {return Row(
children: [
Flexible(
fit: FlexFit.tight,
flex: 1,
child: Container(width: 80, height: 60, color: Colors.red),
),
Flexible(
fit: FlexFit.tight,
flex: 1,
child: Container(width: 120, height: 100, color: Colors.green),
),
Container(width: 90, height: 80, color: Colors.blue),
Container(width: 50, height: 120, color: Colors.orange),
],
);
}
Widget item2() {
return Row(
children: [
Expanded(
flex: 1,
child: Container(width: 80, height: 60, color: Colors.red),
),
Expanded(
flex: 1,
child: Container(width: 120, height: 100, color: Colors.green),
),
Container(width: 90, height: 80, color: Colors.blue),
Container(width: 50, height: 120, color: Colors.orange),
],
);
}
Widget item3() {
return Row(
children: [
Expanded(
flex: 1,
child: Container(width: 80, height: 60, color: Colors.red),
),
Expanded(
flex: 2,
child: Container(width: 10000, height: 100, color: Colors.green),
),
Container(width: 90, height: 80, color: Colors.blue),
Container(width: 50, height: 120, color: Colors.orange),
],
);
}
Widget tip(String content) {
return Text(
"GitLqr >>> $content",
style: TextStyle(
fontSize: 20, color: Colors.white, backgroundColor: Colors.black54, ), ); }}Copy the code
5, the Stack
The Stack allows the child widgets to be stacked on top of each other. The default size is the size of the package content, and the properties are:
- Alignment: Specifies the starting position of the alignment
All the child widgets
Positioned
(Widget) : that’s rightA single child widgets
To locate
- Stretch the child elements to the largest possible size
- Overflow: How to handle overflow, e.g. : overflow is still displayed, can be used
Overflow.visible
class StackDemo1 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Stack(
alignment: AlignmentDirectional.bottomStart,
// fit: StackFit.expand,
overflow: Overflow.visible,
children: [
Image.asset("assets/images/FSA_QR.png"),
Positioned(
left: 20,
bottom: - 50,
child: Container(width: 150, height: 150, color: Colors.red),
),
Positioned(
right: 0,
child: Text(
"lqr",
style: TextStyle(fontSize: 30, color: Colors.white, backgroundColor: Colors.black), ), ) ], ); }}Copy the code
3. Comprehensive cases
class StackDemo2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Stack(
children: [
Image.asset("assets/images/FSA_QR.png"),
Positioned(
left: 0,
right: 0,
bottom: 0,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 8.0),
color: Color.fromARGB(160.0.0.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Welcome to the public account: FSA full stack Behavior",
style: TextStyle(fontSize: 20, color: Colors.white),
),
IconButton(
icon: Icon(Icons.favorite),
color: Colors.red,
onPressed: () => print("Click on favorites"() [() [() [() [() [() }}Copy the code
If this article is helpful to you, please click on my wechat official number: FSA Full Stack Action, which will be the biggest incentive for me. The public account not only has Android technology, but also iOS, Python and other articles, which may have some skills you want to know about oh ~