TECHY360
Everything You Need To Know About Tech

Learn Basics of Flutter, in brief for mobile development

0 22

I decided to try Flutter for myself. To stretch the brain, and so there was something to chill with the men in the kitchen. Things have gone. I started to watch, then read, then write. And everything seems to work out, applications are launched, and what they explain is understandable, everything is simple. But not without a “but” – not everyone explains. And since the platform, the YP, approaches and even the subject area are new to me, this kind of annoying, because you “don’t start”, and you don’t even know what to google: Dart / Flutter / Window / Screen / Route / Widget?

Of course, I did not want to re-read all the documentation of Dart, Flutter and its widgets, because I did not have much time, and I just wanted to take a closer look at Flutter. It would be great if there was a small guide that describes everything you need, but no more, for understanding and writing not too complicated applications on Flutter!

About the guide

Most of the articles on this topic are well written and not complicated. The problem is that most of them require knowledge that is considered basic fundamentals, which, however, are not mentioned in other articles describing the basics. In this series of articles, I want to rectify this situation. Let’s start from scratch and, without leaving any of the above without attention, we will launch one or several applications. In the process, we will learn how to use all the main components , create a unique interface , work with native modules , and, of course, assemble your application for both platforms .

I will write from the perspective of a web developer. Most of you are most likely familiar with the web stack, and the analogy with the familiar platform is better than the analogy with building houses or whatever, Animal, Dog, Foo, Bar …

I will try to outline briefly so as not to delay. And for the most curious, I will leave useful links on the topics discussed.

About the platform

Flutter is a young but very promising platform that has already attracted the attention of large companies that launched their applications . This platform is interesting for its simplicity comparable to the development of web applications, and the speed of work on a par with native applications. High application performance and development speed is achieved through several techniques:

  • Unlike many of today’s well-known mobile platforms, Flutter does not use JavaScript in any form. As a programming language for Flutter, they chose Dart, which is compiled into binary code, thereby achieving the speed of operations comparable to Objective-C, Swift, Java, or Kotlin.
  • Flutter does not use native components , again, in any form, so you do not have to write any layers for communication with them. Instead, like game engines (and you know that games have a very dynamic UI), it draws the entire interface on its own. Buttons, text, media elements, background – all this is drawn inside the graphics engine in Flutter itself. After the above, it is worth noting that the “Hello World” application on Flutter takes up very little space: iOS ≈ 2.5Mb and Android ≈ 4Mb.
  • Flutter uses a declarative approach inspired by the ReactJS web framework based on widgets (in the world of the web called components) to build the UI . For an even greater increase in the speed of the interface, widgets are redrawn as needed – only when something has changed in them (just like Virtual DOM does in the world of front-end).
  • In addition to this, the framework has a built-in Hot-reload , which is so familiar to the web, and still was not available on native platforms.

On the practical benefits of these factors, I highly recommend reading the article by the Android developer who rewrote his application from Java to Dart and shared his impressions. Here I just take out the number of files / lines of code named by him before (written in Java) – 179/12176, and after (rewritten in Dart) – 31/1735. In the documentation you can find a detailed description of the technical features of the platform . And here is another link, if you are interested to see other examples of working applications .

About Dart

Dart is a programming language in which we have to write applications under Flutter. It is very simple, and if you have experience with Java or JavaScript, you will quickly learn it.

I tried to write a review article about Dart, trying to describe only the necessary minimum for learning Flutter. But there are so many nuances in this language that, despite several attempts to write such an article, I still could not make it quite complete and at the same time short. On the other hand, the authors of A Tour of the Dart Language did an excellent job of this.

About training

This topic, like Dart, is very well described in the official guide. I could only copy it here, but I won’t do it.

Without waiting for anything, we go to the installation guide page , select the platform and follow the steps to install the platform on our system. In our editor, we ’ll connect plugins. In the same guide there is an instruction for setting up VS Code and IntelliJ . There are also plugins for Dart and Flutter for your editor (usually you need to install two). We launch the application and check its performance .

Hint for OSX users. I feel sorry for the space occupied by the painted frames of the phone in the iOS emulator, so I turned them off and switched to iPhone 8 (it is not so “long”):

  • Hardware → Device → iOS # → iPhone 8
  • Window → Show Device Bezels

You can live without buttons, because there are hotkeys: Shift + Cmd + H– this is home Cmd + Right– and this is to turn the phone over, the rest can be found in the menu Hardware. But I advise you to turn on the on-screen keyboard, because it is important to understand whether it is possible to work with the application when half of the screen is regularly blocked by the keyboard: Cmd + K(works when the focus is on some input field).

iPhone 8 & iPhone X with frames

iPhone 8 & iPhone X borderless

About the structure

We’ll go into the folder with the generated application and see what we have there. Not with everything, but with the right one:

  • lib/– According to the principles of pub (Dart’s package manager), all the code lies in this subfolder;
  • pubspec.yml– here are written based applications to be installed to run it, just like package.json, but there is a caveat, do not install them through a standard utility Dart’a, as discussed above, and a team Flutter’a: flutter pub get <package_name>;
  • test/“Do you know what is there?” You can run them by calling flutter test;
  • ios/android/– folders with settings for each platform, it indicates what rights are needed to run the application (access to the location, bluetooth), icons and everything that is specific to the platform.

We figured out the structure, go to the folder lib/where the main.dartfile is waiting for us . This, as you can guess, is the same file in which we must run our application. And it starts like in C (and even tons of others) by calling a function main().

About widgets (Hello World here)

In Flutter, everything is built on Widget ‘s: there are views, styles with themes, and state in widgets. There are two main types of widgets: with and without state, but not about that yet. Let’s get it easy.

Remove everything from main.dart . Paste the following code carefully reading the comments:

import 'package: flutter / widgets.dart'; // connect the basic set of widgets

// When Dart launches the application, it calls the main () function
main () => runApp (// and the runApp function launches Flutter
   Text (// this widget, it draws text, such a <span>
     'Hello, World !!!', // first argument is the text to be displayed
     textDirection: TextDirection.ltr, // and here we indicate the direction of the text
   ),
);

runApp(…)accepts a single argument – a widget that will be the root for the entire project. By the way, Hot-reload cannot pick it up, so you will need to restart the application.
Text(…)– Flutter cannot just display a string on the screen. To display the text you must specify TexttextDirection. And this is not text alignment like text-align, if compared with the web, then this is an analog direction. Part of the API for internationalizing an application. Textit won’t work until it knows the direction, but you don’t have to specify it everywhere – next we will analyze how to adjust the direction of the text for the entire application.

Already launched the app? “Hello, World!” Came out! Seems Yes? But something obviously went wrong.

Related Posts
1 of 12

The text is blocked by system information. We have all the screen space at our disposal, and we brought out the widget at its very beginning, where, among other things, system information is displayed. Let’s try moving our text somewhere.

import 'package: flutter / widgets.dart';

main () => runApp (
   Center (// widget that center content
     child: Text (
       'Hello, World!',
       textDirection: TextDirection.ltr,
     ),
   ),
);

Center(…)– This is a widget that allows you to place another widget, passed in the argument child, in the center horizontally and vertically. You will often see childit childrenin Flutter applications, since almost all widgets use these names to transfer widgets that must be drawn inside the called widget.

Widget compositions are used in Flutter to render the UI, change the look, and even transfer data. For example, a widget Directionality(…)sets the text direction for all child widgets:

import 'package:flutter/widgets.dart';

main() => runApp(
  Directionality(
    textDirection: TextDirection.ltr,
    child: Center(
      child: Text('Hello, World!'),
    ),
  ),
);

Let’s look at another very important widget and at the same time transform the look of our application:

import 'package: flutter / widgets.dart';

main () => runApp (
   Directionality (
     textDirection: TextDirection.ltr,
     child: Container (// new widget! <div> in the Flutter world
       // For the Container widget, the color property means the background color
       color: Color (0xFF444444),
       child: Center (
         child: Text (
           'Hello, World!',
           style: TextStyle (// and the text has a widget that stylizes it
             color: Color (0xFFFD620A), // set the text color to it
             fontSize: 32.0, // and font size
           ),
         ),
       ),
     ),
   ),
);

Color(…)– color. The documentation indicates different ways of setting it, but the main thing is simply passing the number to the class constructor. In the example above, we pass the constructor a number written in hexadecimal form, which is very similar to HEX, only at the beginning we added two more characters indicating the degree of transparency of the color, where 0x00 is absolutely transparent, and 0xFF is not transparent at all.

TextStyle(…) – An even more interesting widget, with its help you can set the color, size, thickness, line spacing, add underline and more.

Flutter application written, done! In the docks, you can read how to assemble it for Android and iOS , there are links in the same place to let you know how to send it to the desired Store. To whom this is not enough, I threw a couple more lines about Flutter below, maybe more …

Pro Stateless Widgets

How to use widgets – we’ve figured out, now let’s figure out how to create them. It has already been mentioned above that there are widgets that have a state and that do not have it. So far, we have only used stateless widgets. This does not mean that they don’t have it at all, because widgets are just classes, and their properties can be changed. Just after the widget is rendered, changing its state will not lead to updating this widget in the UI. For example, if we need to change the text on the screen, we will need to generate another widget Textand specify the new content that we want to display. Such widgets can be called constant, if you know what I mean. And they are simple, so let’s start with them.

To create a Stateless widget, you need:

  1. Come up with a beautiful name for a new class;
  2. Inherit a class from StatelessWidget;
  3. Implement a method build()that takes BuildContextas an argument and returns some Widget.
import 'package: flutter / widgets.dart';

main () => runApp (
   Directionality (
     textDirection: TextDirection.ltr,
     child: Center (
       child: MyStatelessWidget ()
     ),
   ),
);

class MyStatelessWidget extends StatelessWidget {
   // annotation @override is needed for optimization, using it we say
   // that the overridden method from the parent class we use
   // we won’t, so the compiler can throw it away
   @override
   Widget build (BuildContext context) {// [context] will be described later
     return Text ('Hello!');
   }
}

Example widget with one argument:

// ...

class MyStatelessWidget extends StatelessWidget {
   // All stateless widget properties must be declared with final, or with const
   final String name; // regular property
   MyStatelessWidget (this.name); // regular constructor

   @override
   Widget build (BuildContext context) {// [context] will be described later
     return Text ('Hello, $ name!');
   }
}

About Stateless and nothing more to add …

About Hot Reload

Please note that when you change the contents of our widget, the application will be automatically redrawn. After we removed the widget from the main()Hot-reload function, I began to help us.

It is also important to understand that due to the launched module for hot swapping, the application runs an order of magnitude slower.

About GestureDetector

In the next section, we will deal with StatefulWidget(with widgets that change when their state changes). In order for this to be interesting, we need to somehow change this state, agree? We will change the state of the widget in response to touches on the screen. To do this, we will use GestureDetector(…)a widget that does not draw anything, but monitors touches on the smartphone screen and reports about it calling the functions transferred to it.

Create a button in the center of the screen, when clicked, a message will be displayed in the console:

import 'package: flutter / widgets.dart';

main () => runApp (
  Directionality (
    textDirection: TextDirection.ltr,
    child: Container (
      color: Color (0xFFFFFFFF),
      child: App (),
    ),
  ),
);

class App extends StatelessWidget {
  @override
  Widget build (BuildContext context) {
    return center (
      child: GestureDetector (// used as a regular widget
        onTap: () {// one of the properties of the GestureDetector
          // This method will be called when the child is clicked
          print ('You pressed me');
        },
        child: Container (// our button will be a container
          decoration: BoxDecoration (// style the container
            shape: BoxShape.circle, // give it a round shape
            color: Color (0xFF17A2B8), // and color it blue
          ),
          width: 80.0,
          height: 80.0,
        ),
      ),
    );
  }
}

Click on the blue button and see the message in the console. We click again and again we see the message in the console. Once again … All right, stop sticking.

Stateful Widgets

StatefulWidget– simple, even simpler than StatelessWidget‘s. But there is a nuance: they do not exist by themselves, for their work we need another class that will store the state of this widget. At the same time, its visual part (the widgets of which it consists) also become its state.

To get started, look at the widget class:

// ...

class Counter extends StatefulWidget {
   // The mutable state is not stored in the widget, but inside the object of a special class,
   // created by the createState () method
   @override
   State <Counter> createState () => _CounterState ();
   // The result of the function is not just an object of the State class,
   // and necessarily State <Our Widget Name>
}

Above, we created an “empty” widget that implemented a very simple method createState(). This separation of presentation and state allows Flutter to greatly optimize the application.

The state object is completely uncomplicated. Moreover, it is almost identical to the ones StatelessWidgetwe wrote above. Its main difference is the parent class.

// ...

class _CounterState extends State <Counter> {
  // Inside it, we can finally declare dynamic variables,
  // in which we will store the state.

  // In this case, this is the hit count
  int counter = 0;

  // And then everything is very simple, we implement the exact same method
  // to draw the widgets that we used in the Stateless class of the widget.
  @override
  Widget build (BuildContext context) {
    // And practically nothing has changed since our last example,
    // but what has changed - I commented:
    return center (
      child: GestureDetector (
        onTap: () {
          // At the moment the button is pressed, we increase the value
          // variable counter.
          setState (() {
            // setState () is needed to call methods
            // widget life cycle and tell it that it’s time to update
            ++ counter;
          });
        },
        child: Container (
          decoration: BoxDecoration (
            shape: BoxShape.circle,
            color: Color (0xFF17A2B8),
          ),
          width: 80.0,
          child: Center (
            child: Text (// print the value of the counter property
              '$ counter', // to monitor its change
              style: TextStyle (fontSize: 30.0),
            ),
          ),
        ),
      ),
    );
  }
}

Note that the class name begins with a bottom underscore. In Dart, all names starting with underscores identify private values. And the state of widgets in Flutter is usually left private, although this is not necessary.

What a wonderful application we have made! This is a great result. But before you finish this part of the course, let’s look at a couple more interesting widgets. Only this time we will write more code, just to make it more interesting. Most of the application should be familiar to you, and the rest you should have already learned to understand:

import 'package:flutter/widgets.dart';

main() => runApp(App());

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.ltr,
      child: Container(
        padding: EdgeInsets.symmetric(
          vertical: 60.0,
          horizontal: 20.0,
        ),
        color: Color(0xFFFFFFFF),
        child: Content(),
      ),
    );
  }
}

class Content extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Counter('Manchester United'),
        Counter('Juventus'),
      ],
    );
  }
}

class Counter extends StatefulWidget {
  final String _name;
  Counter(this._name);

  @override
  State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int count = 0;

@override
   Widget build (BuildContext context) {
     return Container (
       margin: EdgeInsets.only (bottom: 10.0),
       padding: EdgeInsets.all (4.0),
       decoration: BoxDecoration (
         border: Border.all (color: Color (0xFFFD6A02)),
         borderRadius: BorderRadius.circular (4.0),
       ),
       child: Row (
         mainAxisAlignment: MainAxisAlignment.spaceBetween,
         children: [
           // widget is a property of the State class in which it is stored
           // link to the object that created the current state, that is, to our widget
           _CounterLabel (widget._name),
           _CounterButton (
             count
             onPressed: () {
               setState (() {
                 ++ count;
               });
             },
           ),
         ],
       ),
     );
   }
}

class _CounterLabel extends StatelessWidget {
  static const textStyle = TextStyle(
    color: Color(0xFF000000),
    fontSize: 26.0,
  );

  final String _label;
  _CounterLabel(this._label);

  @override
  Widget build(BuildContext context) {
    return Text(
      _label,
      style: _CounterLabel.textStyle,
    );
  }
}

class _CounterButton extends StatelessWidget {
  final _count;
  final _onPressed;
  _CounterButton(this._count, {@required this._onPressed});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        _onPressed();
      },
      child: Container(
        padding: EdgeInsets.symmetric(horizontal: 6.0),
        decoration: BoxDecoration(
          color: Color(0xFFFD6A02),
          borderRadius: BorderRadius.circular(4.0),
        ),
        child: Center(
          child: Text(
            '$_count',
            style: TextStyle(fontSize: 20.0),
          ),
        ),
      ),
    );
  }
}

We have two new widgets: Column()and Row(). Try to figure out what they are doing. And in the next article we will consider them in more detail, as well as see more than one widget that allows you to compose other widgets together, and create a nice application using the Flutter library called Material.

About homework

If you want to read something else at your leisure, here is a list of interesting links:

Get real time updates directly on you device, subscribe now.

Comments
Loading...

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More