First experience of flutter development

Time:2020-2-11

Foreword 1: I will update some columns of flutter text tutorials in succession in the next period

Update progress:At least two articles per week;

Update location:First appeared in the public number, and the second day was updated in nuggets, thoughts and developers’ headlines.

More communication:You can add my wechat 372623326 and follow my micro blog: Code why

I hope you canHelp forward, click to seeGive me more creative power.

1、 Create a flutter project

There are two ways to create a fluent project:Create from the command lineandCreate with development tools

1.1. Create from the command line

It is very simple to create from the command line, just enter the following command at the terminal:

  • Be careful:The name of flutter shall not contain special characters, and hump identification is not allowed
  • After creation, open it with your favorite development tool
flutter create learn_flutter

First experience of flutter development

1.2. Creation through development tools

I can also go through it directly hereAndroid StudioTo create:

  • ChoiceStart a new Flutter project, and then fill in the relevant information, which will not be repeated here

1.3. Default program analysis

Let’s talk about the created application running on the emulator (I choose iPhone emulator here, Android is also available), and we will see the following effects:

First experience of flutter development

Default project analysis:

  • We have analyzed the directory structure before. There is alibFolder, in which we will store our code for the flutter;
  • I opened it and found that there was amain.dart, it was started by our flutterEntry fileThere areMain function

Default code analysis:

  • This is a counter case program. Click the+Symbol, the number shown above will increase;
  • But when we first touch the code in main.dart, we may find manyIncognizanceI don’t know how to write this content;

As a beginner, my suggestion is to delete all the codes and create the codes from zero, so that we can have a very clear structure of the flutter application;

2、 Start flitter code

2.1. Hello World

2.1.1. Hello World requirements

To do any development, we are from the ancestralHello WorldAt first, now our needs come:

  • In the center of the interface, display a hello world;

2.1.2. Implementation of Hello World

Let’s start to write Hello World:

import 'package:flutter/material.dart';

main(List<String> args) {
  runApp(Text("Hello World", textDirection: TextDirection.ltr));
}

Of course, in the above code, we have implemented the display of Hello world on the interface:

  • howeverNo middleThe font is also a little small
  • We will solve these problems later. First, understand the current lines of code;

We are familiar with some of the above codes, some of which are not clear:

  • Like we know about dartThe entries are all main functions, and the fluent is written by dart, so the entry is also the main function;
  • But we importedWhat is material
  • In addition, we call one in the main function.Runapp() functionWhat is it?

Next, we do some analysis on the unknown code.

2.2. Code analysis

2.2.1. Runapp and widget

runAppIt’s a function provided by flutter. When we start a flutter application, we start from calling this function

  • We can click the source code of runapp to view the function
  • We will not analyze the specific source code for the time being (because I have found too many theories, which are not friendly for beginners)
void runApp(Widget app) {
  ... omit code
}

This function lets us pass in one thing:Widget

Let’s talk first.Translation of widget

  • There are many translations of widget in China;
  • People who have done Android, IOS and other development like to translate it intocontrol
  • People who have done Vue, react and other development like to translate it intoassembly
  • If we use Google, the translation of widget should beWidget
  • I didn’t say which translation must be right or wrong, but I personally preferWidget or component

WidgetWhat on earth?

  • When we learn about flutter, we can have a basic understanding from the beginning:Everything in the shuttle is a widget
  • In our IOS or Android development, there are many kinds of interfaces: application, view controller, activity, view, button, etc;
  • But in flutter,These are different widgets
  • That is, our entire applicationWhat you seeAlmost all widgets, evenSetting of inner margin, we also need to use a callPadding's widgetDo it;

The runapp function lets us pass in a widget:

  • But we don’t have a widget now. What should we do?
  • We can import the material library that flutter has provided to us by default to use many of the built-in widgets;

2.2.2. Material design style

What is material?

  • Material is a set promoted by GoogleDesign styleOrdesign languagedesign codeEtc.
  • There are many design specifications, such ascolourTypesetting of wordsResponse animation and overFillWait;
  • Highly integrated in flutterMaterial style widget
  • In our application, we can directly use these widgets to create our application (many will be used later);

Text widget analysis

  • We can use the text widget to display the text;
  • We find that the text widget inherits from statelesswidget, and statelesswidget inherits from widget;
  • So we can pass the text widget into the runapp function
  • There are many properties, but we have learned dart syntax, so you will find that only this.data property must be passed in.
class Text extends StatelessWidget {
  const Text(
    this.data, {
    Key key,
    this.style,
    this.strutStyle,
    this.textAlign,
    this.textDirection,
    this.locale,
    this.softWrap,
    this.overflow,
    this.textScaleFactor,
    this.maxLines,
    this.semanticsLabel,
    this.textWidthBasis,
  });
}

Statelesswidget brief introduction:

  • Statelesswidget inherits from widget;
  • I will introduce its usage in more detail later;
abstract class StatelessWidget extends Widget {
    //... omit code
}

2.3. Code improvement

2.3.1. Improve interface style

We find that the current code is not the final result we want:

  • We may want the text to be centered and larger;
  • Center:You need to use another widget,Center
  • Larger text:You need to set some styles for text text;

We modify the code as follows:

  • We wrapped a center part in the outer layer of the text widget, and let text be its child;
  • In addition, we set a property for the text component: style, the corresponding value is TextStyle type;
import 'package:flutter/material.dart';

main(List<String> args) {
  runApp(
    Center(
      child: Text(
        "Hello World",
        textDirection: TextDirection.ltr,
        style: TextStyle(fontSize: 36),
      ),
    )
  );
}

2.3.2. Improve the interface structure

At present, although we can display HelloWorld, we find that the bottom background is black, and our page is not structured enough.

  • A normal app page should have a certain structure, such asNavigation bar, there will be somebackground coloretc.

In the development process, we do not need to build such a structured interface from scratch. We can use the material library to directly use some encapsulated components to complete the construction of some structures.

We implement it through the following code:

import 'package:flutter/material.dart';

main(List<String> args) {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("CODERWHY"),
        ),
        body: Center(
          child: Text(
            "Hello World",
            textDirection: TextDirection.ltr,
            style: TextStyle(fontSize: 36),
          ),
        ),
      ),
    )
  );
}

First experience of flutter development

Wrap one in the outermost layerMaterialApp

  • This means that we will use the material app style for the whole application, which is convenient for us to design the application. At present, we use two of them;
  • Title: This is the title that is displayed when opening multitasking switching window in Android system; (it can be left blank for now)
  • Home: is the page displayed when the application starts. We passed in a scaffold;

ScaffoldWhat is it?

  • It’s translated asScaffolding, the function of scaffolding is to build the basic structure of the page;
  • So we passed a scaffold object to the home property of materialapp as the widget to start the display;
  • Scaffold also has some properties, such asappBarandbody
  • AppBar is used to design navigation bar. We passed in aTitle Attribute
  • Body is the content part of the page. We passed in a text widget wrapped in the previously created center;

2.3.3. Advanced case realization

We can make more elements in the interface:

  • By the time you write here, you may have foundToo many nestingDon’t worry, we’ll refactor the code later
import 'package:flutter/material.dart';

main(List<String> args) {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("CODERWHY"),
        ),
        body: Center(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Checkbox(
                value: true,
                onChanged: (value) => print("Hello World")),
              Text(
                "Consent agreement",
                textDirection: TextDirection.ltr,
                style: TextStyle(fontSize: 20),
              )
            ],
          ),
        ),
      ),
    )
  );
}

First experience of flutter development

2.4. Code refactoring

2.4.1. Create your own widget

A lot of people who study flutter will benestingDissuasion, when the code is nested too much, the structure is easy to see.

Here are two things I’ll explain first:

  • 1. The whole development process of flutter is to form a widget tree, so it is normal to form nesting.
  • 2. About the code indentation of flutter, we use 2 spaces in more development (most of the 2 spaces in the front-end development, you like 4 spaces, no problem)

However, there are so many nesting when we develop such a simple program. What if the application is more complex?

  • We can encapsulate our code, encapsulate them into our own widget, and create our own widget;

How to create your own widget?

  • In the development of flutter, we can inherit from statelesswidget or statefulwidget to create our own widget class;
  • StatelessWidget:There is no state changing widget, usually this kind of widget just does some display work;
  • StatefulWidget:Widget that needs to save state and may change state;

In the above case, we can use statelesswiidget to refactor the code, so let’s learn how to use statelesswiidget to refactor our code;

Stateful widget we put in a later case to learn;

2.4.2. StatelessWidget

Statelesswidgets are usually those that have no state (or data) to maintain:

  • Their data is usually directly written (the data placed in the widget must be defined as final, why? I’ll talk about stateful widget in the next chapter.);
  • It is passed in from the parent widget and cannot be modified once it is passed in;
  • Data obtained from inheritedwidget for use (this will be explained later);

Let’s take a look at the format of creating a statelesswidget:

  • 1. Let the widget you created inherit from statelesswidget;
  • 2. Statelesswidget contains a method that must be overridden: build method;
class MyStatelessWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Return < returns the widget to be rendered by our widget, such as a text widget >;
  }
}

Analysis of build method:

  • When we get the statelesswidget we created by ourselves, flutter will execute its build method;
  • We need to tell flutter in the build method what elements our widget wants to render, such as a text widget;
  • Statelesswidget can’t actively execute the build method. When the data we use changes, the build method will be executed again;

When is the build method executed? :

  • 1. When our statelesswidget is first inserted into the widget tree (that is, when it is first created);
  • 2. When our parent widget changes, the child widget will be rebuilt;
  • 3. If our widget depends on some data of inheritedwidget, when the data of inheritedwidget changes;

2.4.3. Refactoring case code

Now we can refactor our code with statelesswidget

  • Because our whole code is some data display, there is no data change, just use statelesswidget;
  • In addition, in order to achieve better encapsulation, I split the code into two layers to make the code structure more clear. (for specific splitting methods, I will continue to reflect them in the later cases. At present, we split the two layers first.)

The reconstructed code is as follows:

import 'package:flutter/material.dart';

main(List<String> args) {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("CODERWHY"),
        ),
        body: HomeContent(),
      ),
    )
  }
}

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Checkbox(
              value: true,
              onChanged: (value) => print("Hello World")),
          Text(
            "Consent agreement",
            textDirection: TextDirection.ltr,
            style: TextStyle(fontSize: 20),
          )
        ],
      ),
    );
  }
}

First experience of flutter development

3、 Case practice

3.1. Final effect of case

Let’s take a look at the final effect of the case:

  • In this effect, we will use many untouched widgets;
  • It doesn’t matter. I’ll explain these commonly used widgets one by one;
  • The main purpose of this case is to make you more familiar with the development mode of flutter and the encapsulation process of custom widget;

First experience of flutter development

3.2. Custom widget

In our case, it is obvious that the display of a product is a large widget, which includes the following widgets:

  • Widget of Title: complete with a text widget;
  • Described widget: completed with a text widget;
  • Picture widget: use an image widget to complete;
  • To arrange the above three widgets vertically, we can use a column widget (in the previous chapter, we used row to arrange horizontally)

In addition, the titles, descriptions and pictures of the three displays are different, so we can let the parent widget decide the content:

  • Create three member variables to hold the data passed in by the parent widget
class ProductItem extends StatelessWidget {
  final String title;
  final String desc;
  final String imageURL;

  ProductItem(this.title, this.desc, this.imageURL);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Text(title, style: TextStyle(fontSize: 24)),
        Text(desc, style: TextStyle(fontSize: 18)),
        Image.network(imageURL)
      ],
    );
  }
}

3.3. List data display

Now we can create three productitems to show them:

  • Myapp is consistent with the previous chapter without any change;
  • In homecontent, we use a column because the three productitems we create are arranged vertically
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primaryColor: Colors.blueAccent
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text("CODERWHY"),
        ),
        body: HomeContent(),
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        ProductItem("Apple1", "Macbook Product1", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72j6nk1d4j30u00k0n0j.jpg"),
        ProductItem("Apple2", "Macbook Product2", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72imm9u5zj30u00k0adf.jpg"),
        ProductItem("Apple3", "Macbook Product3", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72imqlouhj30u00k00v0.jpg"),
      ],
    );
  }
}

The operation effect is as follows:

  • Error message: Yellow zebra crossing appears below;
  • This is because in the layout of the flutter, the content cannot exceed the scope of the screen. When it exceeds the scope, it will not automatically become a scrolling effect, but will report the following errors;

How can we solve this problem?

  • We can change column to listview;
  • Listview can make its own subwidgets scroll;

3.4. Case details adjustment

3.4.1. Overall edge distance of interface

What if we want the entire content to be a certain distance from the edge of the screen?

  • We need to use another widget: padding, which has a padding property to set the margin size;
  • Yes, setting the inner margin also uses widget, which is padding;

First experience of flutter development

3.4.2. Product margins and borders

Now we want to add an inner margin and a border to all products. What can we do?

  • We can use a container widget, which has the padding attribute and can set the border through the decoration;
  • We will talk about the container in detail later, let’s use it first;

3.4.3. Space between words and pictures

We want to add some space between the picture and the text. What should we do?

  • Method 1: add an up inner margin or down inner margin to the picture or text;
  • Mode 2: use sizedbox’s widget to set a height attribute, which can increase some distance;

First experience of flutter development

3.5. Final implementation code

Finally, I give the final implementation code:

import 'package:flutter/material.dart';

main(List<String> args) {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primaryColor: Colors.blueAccent
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text("CODERWHY"),
        ),
        body: HomeContent(),
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: ListView(
        children: <Widget>[
          ProductItem("Apple1", "Macbook Product1", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72j6nk1d4j30u00k0n0j.jpg"),
          ProductItem("Apple2", "Macbook Product2", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72imm9u5zj30u00k0adf.jpg"),
          ProductItem("Apple3", "Macbook Product3", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72imqlouhj30u00k00v0.jpg"),
        ],
      ),
    );
  }
}

class ProductItem extends StatelessWidget {
  final String title;
  final String desc;
  final String imageURL;

  ProductItem(this.title, this.desc, this.imageURL);

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(20),
      decoration: BoxDecoration(
        border: Border.all()
      ),
      child: Column(
        children: <Widget>[
          Text(title, style: TextStyle(fontSize: 24)),
          Text(desc, style: TextStyle(fontSize: 18)),
          SizedBox(height: 10,),
          Image.network(imageURL)
        ],
      ),
    );
  }
}

Note: all contents start with the public number. In addition to Flutter, other technical articles will be updated. TypeScript, React, Node, uniapp, mpvue, data structure and algorithm will also update some of their own learning experiences. Welcome everyone’s attention.

Recommended Today

How to realize incremental update function in uni app

As we all know, many apps have the function of incremental update. At the beginning of this year, uni app launched the function of incremental update. Today we will learn a wave. Of course, in order to prevent developers from providing illegal content to users without market approval, many application markets, especially apple, are averse […]