This article has authorized the public account “code egg”, please indicate the source of reprint

In the previous section, we introduced some syntax for Dart and the configuration environment url. In this section, we can begin to understand Flutter

It mainly includes MaterialApp, Scaffold, Text, Image, Icon, Button and AppBar

Flutter runApp

Dart: void main() => runApp(MyApp()); This is the entry to the program. Here you can take a quick look at the source code

voidrunApp(Widget app) { WidgetsFlutterBinding.ensureInitialized() .. attachRootWidget(app) .. scheduleWarmUpFrame(); }/ / /...
static WidgetsBinding ensureInitialized() {
  if (WidgetsBinding.instance == null)
    WidgetsFlutterBinding();
  return WidgetsBinding.instance;
}

/ / /...
void attachRootWidget(Widget rootWidget) {
  _renderViewElement = RenderObjectToWidgetAdapter<RenderBox>(
    container: renderView,
    debugShortDescription: '[root]',
    child: rootWidget
  ).attachToRenderTree(buildOwner, renderViewElement);
}
Copy the code

A WidgetsBinding singleton is created and the passed App is added to rootWidget. The scheduleWarmUpFrame method is a long one

Schedule a frame to run as soon as possible

“Arrange for the framework to run as soon as possible.” Quick start frame

Flutter App

MyApp class inherits from the StatelessWidget and returns an instance of the MaterialApp in the build method. Most of the widgets that you see with the word “Cupertino” are ios-style widgets. We will not talk about ios-style widgets here. Currently, Flutter does not support Cupertino widgets very well. The multi-language support is not very friendly, so let’s move on to the MD-style Android widget. Here we take a look at the MaterialApp constructor and introduce some common parameters

const MaterialApp({
    Key key,
    this.navigatorKey,
    this.home, // The content widget in the home screen
    this.routes = const <String, WidgetBuilder>{}, // The router is connected to a router
    this.initialRoute,
    this.onGenerateRoute,
    this.onUnknownRoute,
    this.navigatorObservers = const <NavigatorObserver>[], 
    this.builder,
    this.title = ' '.// * Similar title
    this.onGenerateTitle, // This value is used to replace the title based on the current language
    this.color, // Theme color, if this value is not set, theme. PrimaryColor, if theme is not set, blue
    this.theme, // App theme style, including theme color, button default color, etc
    this.locale, // Locale is related to multilanguage adaptation
    this.localizationsDelegates,
    this.localeListResolutionCallback,
    this.localeResolutionCallback,
    this.supportedLocales = const <Locale>[Locale('en'.'US')].this.debugShowMaterialGrid = false.this.showPerformanceOverlay = false.this.checkerboardRasterCacheImages = false.this.checkerboardOffscreenLayers = false.this.showSemanticsDebugger = false.this.debugShowCheckedModeBanner = true.// Whether to display the DEBUG banner in debug mode
  })
Copy the code

MaterialApp inherits from StatefulWidget, which, along with MyApp’s inherited class StatelessWidget, is an abstract class that custom widgets typically inherit from in everyday development.

  1. StatelessWidgetIt is a state immutable component. The component constructed by it is generally used to display fixed contents. For example, a fixed list of function buttons needs to be displayed, and the display contents need not be modified according to different interface states
  2. StatefulWidgetIt is a component that can change its state. For example, if we need to obtain data through the network or database and modify the data content displayed by the component lock, we need to passStatefulWidgetTo build. Not that, of courseStatelessWidgetThe function of modifying interface data cannot be implemented, which needs to be involvedState managementI will talk about it later when I have a chance. I will bury the pit here first.

Flutter Scaffold

Scaffolding provides a Scaffold that can quickly build a MaterialDesign style interface. Let’s take a look at the scaffolding constructors and see some of the scaffolding constructors that are commonly used.

const Scaffold({
    Key key,
    this.appBar, // The bar at the top of the interface that needs to return an AppBar instance
    this.body, // The content part of the interface
    this.floatingActionButton, / / suspension parts, can be set by floatingActionButtonLocation position
    this.floatingActionButtonLocation,
    this.floatingActionButtonAnimator,
    this.persistentFooterButtons,
    this.drawer, // Side slide drawer part, from the left (should be related to the language, and the same direction as the text)
    this.endDrawer, // Slide the drawer out from the right side
    this.bottomNavigationBar, // The bottom navigation bar, which is usually seen as the bottom TAB switch
    this.bottomSheet, // Show the bottomsheet that pops up from the bottom
    this.backgroundColor, // The background color of the interface
    this.resizeToAvoidBottomPadding = true.// Avoid the body being filled with bottom pop-ups, such as the input keyboard
    this.primary = true.// Whether the Scaffold needs to be displayed at the top of the screen
  })
Copy the code

Let me draw a picture. It’s simple

Once we understand the overall structure of the Scaffold, we use the constructor to understand the usage of the widgets from top to bottom

AppBar
AppBar({
    Key key,
    this.leading, // Set the button at the front of the AppBar, for example, set the return button we need, etc
    this.automaticallyImplyLeading = true.// Whether to use the default generated button of leading. If you replace the default button of leading, you'd better set this property to false
    this.title, // The component that the AppBar needs to display, passing in an instance of the Widget, usually using Text to display a title
    this.actions, // Some action components that hover at the end of AppBar, such as a common "... "at the end Click the button to pop up a Menue for the user to choose from
    this.flexibleSpace, // AppBar background, you can set the color, background image, etc
    this.bottom, // bottom is used to display the top navigation TAB
    this.elevation = 4.0.this.backgroundColor, // The background color of AppBar can be changed without flexibleSpace if only the color needs to be changed
    this.brightness,
    this.iconTheme, // The default style of the button
    this.textTheme, // The default style of the text
    this.primary = true.this.centerTitle, // Whether to center the title shown
    this.titleSpacing = NavigationToolbar.kMiddleSpacing, // White space on both sides of AppBar title
    this.toolbarOpacity = 1.0.this.bottomOpacity = 1.0,})Copy the code

Before showing the demo of AppBar, let’s first learn the basic components Text, Image, Icon, Button distribution for displaying Text, images, ICONS, and buttons

Text
const Text(this.data, { // Text Specifies the Text to display
    Key key,
    this.style, // the TextStyle, including the color, size, spacing, etc., will not continue to show the TextStyle constructor, otherwise I am afraid that people do not want to continue to see the TextStyle constructor, I will use an example later
    this.textAlign, // See the TextAlign class for more information about how text is aligned: left, right, center, etc
    this.textDirection, // Text direction, LTR (left to Right) or RTL (right to Left)
    this.locale, 
    this.softWrap, // Whether to wrap text when a line is not displayed
    this.overflow, // Which way to omit unshown content if the limit is exceeded
    this.textScaleFactor, // Text scale
    this.maxLines, // Maximum number of rows to display
    this.semanticsLabel,
  })
Copy the code

Next, we will show some examples of Text. The following examples will directly replace the contents displayed in the HomePage, and the rest are the same. Next, please pay attention to Text.

import 'package:flutter/material.dart';

void main() => runApp(DemoApp());

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false, theme: ThemeData(primarySwatch: Colors.lightBlue), home: HomePage(), ); }}class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Container(
          padding: const EdgeInsets.only(top: 10.0),
          child: Center(
              child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Black text display on green background',
                  style: TextStyle(
                      color: Colors.black, // Set text color, cannot be set at the same time as foreground
                      fontSize: 24.0.// Font size
                      letterSpacing: 2.0.// The interval between each characterbackground: Paint().. color = Colors.green)),/ / the background color
              Text('This is a text display underlined in red',
                  style: TextStyle(
                      color: Colors.black,
                      fontSize: 24.0.// Underline, underline, underline, underline
                      // Different styles can be viewed by modifying the code themselves
                      decoration: TextDecoration.underline,
                      / / text decorative thread type, in addition to solid and double, dotted, dashed, wavy optional
                      decorationStyle: TextDecorationStyle.solid,
                      // The color of the decorative threaddecorationColor: Colors.red)) ], )), )); }}Copy the code

This part of the code to view the source codetext_main.dartfile

The final display effect is as follows:

Image

As usual, let’s look at the Image constructor first

const Image({
    Key key,
    ImageProvider is an instance of ImageProvider, but ImageProvider is an abstract class, and Flutter already provides the following
    // AssetImage, NetworkImage, FileImage, MemoryImage
    Asset, Image.network, image.file, image.memory,
    // Load images from asset file, network, file, and memory
    @required this.image, 
    this.semanticLabel,
    this.excludeFromSemantics = false.this.width, // Image width
    this.height, // Image height
    this.color, // Image background color
    this.colorBlendMode, // Mix color and image mode (this value is more than one, can try one by one)
    this.fit, // Fill, cover, contain, fillWidth, fillHeight, scaleDown, none
    this.alignment = Alignment.center, // Alignment
    this.repeat = ImageRepeat.noRepeat, // If the space is not filled, repeat the display
    this.centerSlice,
    this.matchTextDirection = false.this.gaplessPlayback = false.this.filterQuality = FilterQuality.low,
  })
Copy the code

Ok, ok, I know you want to try it again, but before you do that, you need to prepare a local image, and then create a new folder in the root directory of your project, the lib folder, called images, and put your images in that folder. After that, open pubspec.yaml and register the image resource file

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # Register resource files here. In the future, you can also register images folder only. It will automatically read internal files
  assets:
    - images/ali.jpg
Copy the code

Once the registration is complete, you can continue to enjoy the code ~

class HomePage extends StatelessWidget {
  final String _assetAli = 'images/ali.jpg';
  final String _picUrl =
      'https://timg05.bdimg.com/timg?wapbaike&quality=60&size=b1440_952&cut_x=143&cut_y=0&cut_w=1633&'
      'cut_h=1080&sec=1349839550&di=cbbc175a45ccec5482ce2cff09a3ae34&'
      'src=http://imgsrc.baidu.com/baike/pic/item/4afbfbedab64034f104872baa7c379310b551d80.jpg';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Container(
          padding: const EdgeInsets.only(top: 10.0),
          child: Center(
              child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              // This way of displaying images will have the same effect as the next way
              Image(image: AssetImage(_assetAli), width: 80.0, height: 80.0),
              // Use these convenient methods to load images
              Image.asset(_assetAli, width: 80.0, height: 80.0),
              // Load a network image
              Image.network(_picUrl,
                  height: 80.0.// horizontal repeat
                  repeat: ImageRepeat.repeatX,
                  // mediaquery.of (context).size Retrieves the width and height of the upper container
                  width: MediaQuery.of(context).size.width),
              // By setting the blend mode, you can see that the image display style has been modified
              Image.asset(_assetAli,
                  width: 80.0, height: 80.0, color: Colors.green, colorBlendMode: BlendMode.colorDodge),
              // The specified asset image will be loaded first. After the network image is successfully loaded, the network image will be displayed in fade out mode
              // Cover the smaller edges and cut the larger ones
              // contain the largest folder and the smallest one is left blank
              // Fill compresses the larger side
              // fitHeight, fitWidth is filled according to the length and width respectively
              FadeInImage.assetNetwork(
                  placeholder: _assetAli, image: _picUrl, width: 120.0, height: 120.0, fit: BoxFit.cover),
              // ICONS have fewer properties. You need to pass in an IconData instance. Flutter provides many ICONS.
              // But in reality we need to add our own icon and bury the pit here.
              // size indicates the size of the icon, color indicates the color of the icon, and Theme is used to obtain the Theme color
              Icon(Icons.android, size: 40.0, color: Theme.of(context).primaryColorDark) ], )), )); }}Copy the code

This part of the code to view the source codeimage_main.dartfile

The final effect is as follows:

Button

The various types of Folders that Flutter provides are almost identical. Here are some of the more common ones to show their effects. Commonly used mainly RaisedButton, FlatButton, IconButton, OutlineButton, MaterialButton, FloatActionButton, FloatingActionButton. Extended

Button has an onPress parameter, which is of type VoidCallback. VoidCallback is a type parameter with no parameters and no return value. If this parameter is passed in as null then the button is unclickable and has no clickable effect, as you can see in the example. There is also the child parameter, which is passed in the content you want to display, such as Text, Icon, etc. Other parameters can be basically known by the parameter name, this is not extended (look at the source code I am afraid you do not want to continue to read…)

Talk is cheap, show me the code

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        padding: const EdgeInsets.only(top: 10.0),
        child: Center(
            child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
              onPressed: () {
                print('This is a Rased Button can be clicked');
              },
              child: Text('Raised Enable'),
            ),
            RaisedButton(onPressed: null, child: Text('Raised Disable')),
            FlatButton(
              onPressed: () => print('This is a Flat Button can be clicker'),
              child: Text('Flat Enable'),
            ),
            FlatButton(onPressed: null, child: Text('Flat Disable')),
            IconButton(icon: Icon(Icons.android), onPressed: () {}),
            IconButton(icon: Icon(Icons.android), onPressed: null),
            MaterialButton(onPressed: () {}, child: Text('Material Enable')),
            MaterialButton(onPressed: null, child: Text('Material Disable')),
            OutlineButton(onPressed: () {}, child: Text('Outline Enable')),
            OutlineButton(onPressed: null, child: Text('Outline Enable')),
          ],
        )),
      ),
      floatingActionButton:
          FloatingActionButton.extended(onPressed: () {}, icon: Icon(Icons.android), label: Text('Android')), floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, ); }}Copy the code

This part of the code to view the source codebutton_main.dartPart of the

The final effect:

This article finally comes to the end, leaving 3 holes to be solved later

The final code address is still needed:

  1. The code covered in this article: Demos

  2. BLoC mode based on a project of Guo Shen Cool Weather interface to achieve state management: Flutter_weather

  3. One course (I bought the code specification at that time and wanted to see it, the code update would be slow, although I wrote the code following the lessons, I still made my own modifications, which made me uncomfortable in many places, and then changed it to my own implementation) : Flutter_shop

If it is helpful to you, please remember to give me a Star. Thank you in advance. Your recognition is the motivation to support me to continue writing