Flutter layout

Alignment

The Container class has an alignment property that controls the position of the Container’s children relative to itself. In our iOS development, we know that the origin of the coordinate system is in the top left corner. In the Flutter, the origin of the coordinate system is in the center of the parent control. You can use this alignment property to control the position of the child control in the parent control. The two parameters are x and y of type double. The value ranges from -1 to 1. When 0,0 indicates that the child control is in the center of the parent control. When 1,0, means that the child control is located in the right side of the x direction, and in the center of the y direction; -1 or -1 indicates that the child control is in the upper left corner of the parent control. Somewhat similar to the anchorPoint property of a CALayer. The code is as follows:

Row

Row represents a horizontal layout and has a children property to hold its child controls. The code is as follows:

At first we tried the alignment property. When it is 0,0, the Text position defaults to the center of the screen. Why is it that when we replace our Row here, the child control of the Row is not in the center of the screen?

mainAxisAlignment

Both rows and columns have a mainAxisAlignment property called main alignment. The default is mainAxisAlignment. Start means to start along the main axis, left to right for Row and top to bottom for Column. MainAxisAlignment. SpaceAround: will the rest of the space distribution of average MainAxisAlignment. SpaceBetween: will the rest of the space allocation between child controls MainAxisAlignment. SpaceEvenly: such as spacing distribution of child controls

crossAxisAlignment

Cross axis alignment,start,end,center are easy to understand. Stretch will stretch the child control. However, the baseline is used less, and it will report errors if used alone, so it needs to be combined with Text TexttextBaselineProperties. If this parameter is not set, as shown in the following figureCrossAxisAlignment.baselineandTextBaseline.alphabeticAligns horizontally against the height of the control or, if set, against the baseline text within the control.

Column

This corresponds to Row, which is horizontal, and this Column is vertical

class LayoutDemo extends StatelessWidget { const LayoutDemo({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Container( color: Colors.green, alignment: Alignment(0, 0), child: Column( children: [ Container( child: Icon(Icons.add, size: 180,), color: Colors.red, ), Container( child: Icon(Icons.ac_unit, size: 120,), color: Colors.yellow, ), Container( child: Icon(Icons.access_alarm, size: 60,), color: Colors.blue, ), ], ), ); }}Copy the code

The display effect is shown as follows:

mainAxisAlignment

This is similar to Row

crossAxisAlignment

This is similar to Row

Stack

This is for the z-axis layout, where row is the X-axis and column is the Y-axis. The children array is placed first at the bottom and last at the top, closest to the user.

class LayoutDemo extends StatelessWidget { const LayoutDemo({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Container( color: Colors.green, alignment: Alignment(0, 0), child: Stack( children: [ Container( child: Icon(Icons.add, size: 180,), color: Colors.red, ), Container( child: Icon(Icons.ac_unit, size: 120,), color: Colors.yellow, ), Container( child: Icon(Icons.access_alarm, size: 60,), color: Colors.blue, ), ], ), ); }}Copy the code

APP display effect:

alignment

The Stack has an alignment property that controls the position of all child controls relative to the largest child control

class StackDemo extends StatelessWidget { const StackDemo({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Stack( alignment: Alignment.bottomRight, children: [ Container( child: Icon(Icons.add, size: 180,), color: Colors.red, ), Container( child: Icon(Icons.ac_unit, size: 120,), color: Colors.yellow, ), Container( child: Icon(Icons.access_alarm, size: 60,), color: Colors.blue, ), ], ); }}Copy the code

Positioned

C-stacks would be Positioned in a way that would be a little bit similar to the constraints that we have in iOS, in terms of spacing up, left or something like that

class StackDemo extends StatelessWidget { const StackDemo({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Stack( children: [ Positioned( child: Container( child: Icon( Icons.add, size: 180, ), color: Colors.red, ), ), Positioned( child: Container( child: Icon( Icons.ac_unit, size: 120, ), color: Colors.yellow, ), ), Positioned( top: 20, left: 20, right: 20, child: Container( child: Icon( Icons.access_alarm, size: 60, ), color: Colors.blue, ), ), ], ); }}Copy the code

Expanded

Expanded is a common layout Container like Container. It is used to fill layouts. With Expanded layouts, there is no spacing on the main axis, so when Expanded is used in Row, the width Settings of child controls are meaningless, whereas when Expanded is used in Column, The height of the child control is meaningless. Here’s an example of Column:

class LayoutDemo extends StatelessWidget { const LayoutDemo({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Container( color: Colors.green, alignment: Alignment(0, 0), child: Column( children: [ Expanded( child: Container( child: Icon(Icons.add, size: 180,), color: Colors.red, ), ), Expanded( child: Container( child: Icon(Icons.ac_unit, size: 120,), color: Colors.yellow, ), ), Expanded( child: Container( child: Icon(Icons.access_alarm, size: 60,), color: Colors.blue, ), ), ], ), ); }}Copy the code

AspectRatio

AspectRatio is a container class that has an attribute AspectRatio representing the AspectRatio. If the width is specified, the height is automatically calculated from this aspectRatio; If the height is specified, the width can be automatically calculated according to aspectRatio. The following code specifies that the height of the parent view is 100, the aspectRatio widthratio is 2, the width of the child view is 200, and the width of the parent view is also 200.

class LayoutDemo extends StatelessWidget { const LayoutDemo({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Container( color: Colors.green, alignment: Alignment(0, 0), child: Container( color: Colors.blue, height: 100, child: AspectRatio( aspectRatio: 2, child: Icon( Icons.add, ), ), )); }}Copy the code

Management of Flutter state

So many of the classes I’ve shown you are stateless, which means you can’t update your UI after you display it, and if you want to update your UI in real time, you can’t inherit from stateless classes. Let’s start with an example where the count changes but the display doesn’t changeRemember to modify the Home view of your APPThen click the plus button in the lower right corner of the screen, you can find that the console printed that the value of count has changed, but the interface still displays 0Let’s solve this problem by changing the StateManagerDemo inheritance to StatefulWidget and implementing the createState method to return a custom State object that implements the build method. Note also that the setState method is called in the button’s click method. So every time you click the plus button you can update the UI in real time. After the transformation, it is shown in the picture below:

The bottom TabBar of the project

So far, we’ve covered some of the basics of Flutter. Next, let’s start making a simple APP that mimics wechat. We should all have experience. No matter how much theoretical knowledge we learn, it is difficult to really master a subject of knowledge unless we start to type code and apply it in a project.

Create a new flutter project named Wechat_demo:

Delete the redundant code, you can write it all again:

Create the TabBar and item at the bottom. The default type is white, which makes it look ugly, so change it to fixed. You can also set fixedColor:

BottomNavigationBar has a property, currentIndex, that represents the currently selected subscript. We can control which button is selected by setting its value. Now that we need to change the UI, we need to change the StatelessWidget to the StatefulWidget. There’s another parameter, onTap, that calls the click event back and forth. I’m going to click on the event, I’m going to switch currentIndex, I’m going to setState, and I’m going to click on the switch. We put the bottomNavigationBar code in a new file rootPage. The code is as follows:Remember to modify the main.dart fileIn this way, the bottom TabBar of the APP can be displayed and clicked. When clicking on each item, the bottomNavigationBar of the flutter comes with animation…

We know that Scaffold also has a body attribute that represents what is displayed on the screen. We need an AppBar for each item interface, which may mean that the body property also needs a Scaffold to display the content for each of our items.You can see the wechat home page is probably out, but when you click it will only show the wechat page, how to switch different pages, surely need an array, to store the corresponding each page.

And then in the body, we return the body based on our _currentIndexClicking on each item will jump to the corresponding interface, and the main frame of the APP is set up.

conclusion

Today we will focus on the three layout classes of Flutter: Row, Column, and Stack, and some of their properties. Then there are stateful widgets and stateless widgets. Finally, we build the bottom bottomNavigationBar and page switching function of the wechat APP that we want to do