Developing a UI with Flutter

Hi, Habr! We present to your attention the translation of the article " Building Layouts ". 3r33333.  
3r33333.  

Today we learn:

3r33333.  
 
How UI build mechanics work on Flutter
 
How to typeset screens horizontally and vertically 3r3r888.  
How to roll up the screen using Flutter
 
3r33333.  
The result of today's lesson will be the following screen
 
3r33333.  
Developing a UI with Flutter 3r33333. 3r33333.  
link 3r33333.  
3r33333.  
It is also necessary to fix the pubspec.yaml configuration file (something like gradle for android and cocoa pods in iOS, we can add external dependencies in it). The text of the file itself can be downloaded here 3r33333.  
3r33333.  
The source code of the project can be downloaded here - it must be placed in the file main.dart
 
3r33333.  

Step 1: Screen diagram

3r33333.  
To begin with we will break the model into simple elements
 
3r33333.  
 
Define the rows and columns 3r3r888.  
Determine whether the layout of the grid? 3r388.  
Are there overlapping elements 3r3r888.  
Need tabs for user interface? 3r388.  
Pay attention to areas that require alignment or padding 3r3r888.  
3r33333.  
First, we define the main large elements. In this example, 4 elements are arranged in the form of a column: a picture, two lines and a test block
 
3r33333.  
3r33333.  
3r33333.  
Next, analyze each line. The first line, which is called the "Title", has 3 children - a column of text, an icon of a star, and a number. The first column contains 2 rows. The first column takes up a lot of space, so you should wrap it in an extensible widget. 3r33333.  
3r33333.  
3r33333.  
3r33333.  
The next row, called the button section, also has 3 children. Each of them contains a picture and text. 3r33333.  
3r33333.  
3r3115. 3r33333.  
3r33333.  
Finally we laid out the layout into simple elements. The easiest way is to use a bottom-up approach for display layout. In order to avoid complex structure, break the UI into variables and functions. 3r33333.  
3r33333.  

Step 2: Construct the header row

3r33333.  
First, we need to build the left column of the header section. Inserting a column inside an expandable widget stretches the column to use all the remaining space in the row. Set the crossAxisAlignment property for CrossAxisAlignment.start to align the column to the beginning of the row. 3r33333.  
3r33333.  
Placing a line of text inside the container allows you to activate indents. The second child in the column is also text, it is displayed in gray. The last two elements of the star icon are drawn in red and the text with the value "41". Place the whole line in the container and add indents of 32 pixels on each side. The code to perform these actions is presented below
 
3r33333.  
3r33337. 3r33338. class MyApp extends StatelessWidget {
@override
Widget build (BuildContext context) {
Widget titleSection = Container (
Padding: const EdgeInsets.all (32.0),
Child: Row (
Children:[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children:[
Container(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
'Oeschinen Lake Campground',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
Text(
'Kandersteg, Switzerland',
style: TextStyle(
color: Colors.grey[500],
),
),
],
),
),
Icon (
Icons.star,
Color: Colors.red[500],
),
Text ('41 '),
],
),
);
//3r3723.} 3r33333. 3r33333.  

Step 3: Build a row of buttons

3r33333.  
The button section consists of 3 columns, which are built according to a similar principle - the icon above the text line. The column in this line is filled evenly and the text and icons are drawn in the main color, which is chosen blue in our project in the build () method. 3r33333.  
3r33333.  
3r33337. 3r33338. class MyApp extends StatelessWidget {
@override
Widget build (BuildContext context) {
//3r3723.
return MaterialApp (
title: 'Flutter Demo',
theme: ThemeData (3rr3372.  
Since the build code of each row will be almost identical, it will be most efficient to use a nested function, such as buildButtonColumn (), which includes an icon and text and returns a column with this widget. 3r33333.  
3r33333.  
3r33337. 3r33338. class MyApp extends StatelessWidget {
@override
Widget build (BuildContext context) {
//3r3723.
Column buildButtonColumn (IconData icon, String label) {
Color color = Theme.of (context) .primaryColor;
Return Column (
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children:[
Icon(icon, color: color),
Container(
margin: const EdgeInsets.only(top: 8.0),
child: Text(
label,
style: TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: color,
),
),
),
], 3r33372.);
}
//3r3723.} 3r33333. 3r33333.  
The build function adds an icon directly to the column. Place the text in the container to add indents and separate it from the icon. Construct each row of these columns by calling a function, and passing the icon and text inside the column. Align the column along the main axis using MainAxisAlignment.spaceEvenly, arranging free space before, between and after each column. 3r33333.  
3r33333.  
3r33337. 3r33338. class MyApp extends StatelessWidget {
@override
Widget build (BuildContext context) {
//3r3723.
Widget buttonSection = Container (
Child: Row (
MainAxisAlignment: MainAxisAlignment.spaceEvenly,
Children:[
buildButtonColumn(Icons.call, 'CALL'),
buildButtonColumn(Icons.near_me, 'ROUTE'),
buildButtonColumn(Icons.share, 'SHARE'),
],
),
);
//3r3723.} 3r33333. 3r33333.  

Step 4: Build the description section

3r33333.  
We define a description section that is rather long. Place the text in the container and add padding 32 pixels from each edge. 3r33333.  
3r33333.  
3r33337. 3r33338. class MyApp extends StatelessWidget {
@override
Widget build (BuildContext context) {
//3r3723. Widget textSection = Container (
Padding: const EdgeInsets.all (32.0),
Child: Text (
'' '
Biblisalp in the Bernese Alps. Situated ?578) "It is one of the larger Alpine Lakes. It was followed by a trip through the mountains. , and riding the summer toboggan run.
'' ',
softWrap: true,
),
);
//3r3723.} 3r33333. 3r33333.  

Step 5: Construct a section with the image 3r3333330. 3r33333.  
Three of the four columns have already been built, it remains to do only the image column. The image that is used in this project is available online under the Creative Commons license. But it is big and it will load slowly. In step ? we added an image to our project and updated the configuration file, now we add a link to it in our code. 3r33333.  
3r33333.  
3r33337. 3r33338. Return MaterialApp (
//
body: ListView (
children:[
Image.asset(
'images/lake.jpg',
height: 240.0,
fit: BoxFit.cover,
),
//
],
),
//3r3372.); 3r33333. 3r33333.  
BoxFit.cover tells the Flutter framework that the image should be as small as possible, but at the same time cover the entire rendering area. 3r33333.  
3r33333.  
Step 6: Combine it all

3r33333.  
In the final step we will collect all the pieces of our code together. The widget is organized in a ListView, not a Column, because the ListView automatically scrolls while scrolling on a small device. 3r33333.  
3r33333.  
3r33337. 3r33338. //3r3723. return MaterialApp (
title: 'Flutter Demo',
theme: ThemeData (
primarySwatch: Colors.blue,
),
home: Scaffold (
appBar: AppBar (3r3r72. 337223372. ??? .723333 .723333 .723333 .3343333 .723 .3343333 .723 .3343333 .3343333 .7233333 .7233333 .33) Lakes'),
),
Body: ListView (
Children:[
Image.asset(
'images/lake.jpg',
width: 600.0,
height: 240.0,
fit: BoxFit.cover,
),
titleSection,
buttonSection,
textSection,
], 3rr-3372.),
), 3r3722.);
//3r3364. 3r33333. 3r33333.
! function (e) {function t (t, n) {if (! (n in e)) {for (var r, a = e.document, i = a.scripts, o = i.length; o-- ;) if (-1! == i[o].src.indexOf (t)) {r = i[o]; break} if (! r) {r = a.createElement ("script"), r.type = "text /jаvascript", r.async =! ? r.defer =! ? r.src = t, r.charset = "UTF-8"; var d = function () {var e = a.getElementsByTagName ("script")[0]; e.parentNode.insertBefore (r, e)}; "[object Opera]" == e.opera? a.addEventListener? a.addEventListener ("DOMContentLoaded", d,! 1): e.attachEvent ("onload", d ): d ()}}} t ("//mediator.mail.ru/script/2820404/"""_mediator") () (); 3r33333.
3r33333.
+ 0 -

Add comment