The article will guide Flutter newbies to understand:
We will build the layout according to this app:
In this article, I will explain the Flutter approach, about the layout and show how to place a widget on the screen. Then will introduce some commonly used layout widgets.
If you haven’t set up your environment yet , follow this tutorial:
The first step is to break the layout into the basic components:
First, identify the big components first. In the example below, 4 elements are arranged in a column: 1 image, 2 rows, and 1 block of text.
Next, diagram each row. The first row - Title - has 3 children: 1 text column, a star icon, and a number. Its first child component is a column of two lines of text. The first column takes up a lot of space so it will have to be wrapped in the Expanded widget.
The second row - Button - also has 3 children: Each child component is a column consisting of icons and text.
Once the layout has been determined, the easiest way to implement it is to write the UI from the bottom up. To make it easier to see and avoid getting confused by nesting lots of code, put some code in different variables and functions.
First, you’ll build the column to the left of the title area. Add the following code at the top of the build () function in the MyApp class :
Widget titleSection = Container(
padding: const EdgeInsets.all(32),
child: Row(
children: [
Expanded(
/*1*/
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/*2*/
Container(
padding: const EdgeInsets.only(bottom: 8),
child: Text(
'Oeschinen Lake Campground',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
Text(
'Kandersteg, Switzerland',
style: TextStyle(
color: Colors.grey[500],
),
),
],
),
),
/*3*/
Icon(
Icons.star,
color: Colors.red[500],
),
Text('41'),
],
),
);
1 Place Column inside the Expanded widget so that the column spans all the rows of the row. Set attributes crossAxisAlignment is CrossAxisAlignment.start to set the column to the row starting position.
2 Put the first row of text inside a Container so you can padding. The second child in the column is also text, displaying gray.
3 2 last items are the star icon in the title row, the red and the text “41”. Both rows are in a Container and 32 pixels from each side.
The button row area consists of 3 columns that use the same layout - an icon above a row of text. The columns in this row are spaced evenly, the text and icons are primary colors.
The code for each column is identical, so we create a private method helper named buildButtonColumn , get color, Icon and Text, return a column with widgets of the color received.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// ···
}
Column _buildButtonColumn(Color color, IconData icon, String label) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, color: color),
Container(
margin: const EdgeInsets.only(top: 8),
child: Text(
label,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w400,
color: color,
),
),
),
],
);
}
}
This function adds the icons directly to the column. Text is in Container with margin top-only, splitting text with icon.
Place a row containing the columns by calling the function and passing in the color, Icon and text that identifies that column. Align columns by the main axis using MainAxisAlignment.spaceEvenly to arrange the spaces evenly before, during and after each column. Add the code below titleSection in the build () function :
Color color = Theme.of(context).primaryColor;
Widget buttonSection = Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildButtonColumn(color, Icons.call, 'CALL'),
_buildButtonColumn(color, Icons.near_me, 'ROUTE'),
_buildButtonColumn(color, Icons.share, 'SHARE'),
],
),
);
Add button section to body:
Specify the text section as a variable. Place the text in the Container and add padding on each side. Add the code below buttonSection :
Widget textSection = Container(
padding: const EdgeInsets.all(32),
child: Text(
'Lake Oeschinen lies at the foot of the Blüemlisalp in the Bernese '
'Alps. Situated 1,578 meters above sea level, it is one of the '
'larger Alpine Lakes. A gondola ride from Kandersteg, followed by a '
'half-hour walk through pastures and pine forest, leads you to the '
'lake, which warms to 20 degrees Celsius in the summer. Activities '
'enjoyed here include rowing, and riding the summer toboggan run.',
softWrap: true,
),
);
Setting softwrap = true , the text line will fill the column width before wrap at word boundaries. Add section text to the body:
3 out of 4 components have been completed, leaving only the image. Add an image file to the following example:
Now you can reference the image in the code:
BoxFit.cover shows that the image will be as small as possible but will fill the void surrounding it.
This is the final step, placing all the components in a ListView rather than Column because ListView supports scrolling when the app runs on small screen devices.
Here is finished.
#flutter #dart