Just to clarify

Instead of talking about the setup of the Flutter environment and other pre-operations (just to mention some pothholes I stepped on while installing it), I’ll go straight to my own experience with the development of the Flutter (which actually only took two to three weeks). Flutter is awesome, but the ecological environment is really less. Currently RN is used by more people.

Pits encountered during installation:

  • It is best not to install 1.17.0 for the Flutter SDK, because when I install the flutter run command line I keep getting various errors. I will not get them if I switch to a lower version, as of now. I won’t make any mistakes.
  • SDK download too slow if you can change the thunder download, very fast.
  • Remember to open the virtual Settings (generally the first installation need to enter the BIOS interface to modify), not friends baidu, thank you.
  • In the environment variables, remember to configure the domestic mirror (PUB_HOSTED_URL: pub.flutter_storage_base_url :https://storage.fl…).

  • Add a command line to the environment variable

Begin to learn

When you can start flutter and see something like the image below, congratulations, you are starting from zero.

Basic learning materials

It is recommended to look at the official documents first, and you can have a general overview, because at the beginning, you can’t remember so many things, as long as you have an impression. Don’t memorize it, just look it up when you need it, because I’m doing the same thing myself now, hahaha.

Learning video

I have come to promote the jspang god……

video

Recommend must-see knowledge

Some basic information about Flutter practice (and there are really few components in Flutter, but they are all good because they are not the main component)

Be sure to check out the chapter on Flutter for Web Developers (I’m a Web developer myself and haven’t worked with other app frameworks before).

We’ll see later when we need to use it

Here is a website about flutter components. There are many, though not all, websites about flutter components.

Basic knowledge of

The dart grammar

I think that flutter is a little bit like Java (my Java is only at the university textbook level). If you look at flutter practice above, you will know something about it, that’s enough. Actually, I didn’t go out of my way to learn Dart myself. But it has some nice operators, like? . /?? And so on…

Introduction of the Widget

Almost every object in Flutter is a Widget. Unlike the “controls” in native development, the concept of widgets in Flutter is broader. Widgets can represent not only UI elements but also functional components such as: GestureDetector widgets for gesture detection, themes for APP Theme data delivery, and so on, while controls in native development usually just refer to UI elements. Later in this article, we may use the terms “controls” and “components” when describing UI elements, but the reader needs to know that they are widgets, just different expressions in different scenarios. Because Flutter is primarily used to build user interfaces, for the most part, readers can think of a widget as a control without getting too hung up on the concept.

The main point here is to understand the difference between a StatelessWidget and a StatefulWidget. (If you can’t understand it, you can have a general understanding of it, because I don’t understand it very well, and I will know it when I use it.)

StatelessWidget (Personal Understanding)

Similar to a static page/component that does not require data interaction or only relies on the configuration information of the object itself, and is used to display the given information, can inherit this.

StatefulWidget (Personal Understanding)

This is inherited when you need to do things like data interaction (mostly this one), which is supplemented by callback functions such as initState and dispose that can be overridden.

To summarize, when our Widget is a StatelessWidget, its content cannot be changed once it is created. In contrast, StatefulWidget does.

Base component libraries? Material cow force

This is the official base component library, which is often used in our development. In terms of component libraries, I personally feel a bit like the backbone of a page, depending on what you want to add to it. Why do you say that? Because it gives us the basic skeleton of a page (top title, body, bottom navigation, and so on). Dart (lib/main.dart). Dart (lib/main.dart

import 'package:flutter/material.dart';// Introduce the Material component

void main() => runApp(MyApp());/ / the main entry

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,/ / theme color
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),// This is the component displayed on the homepage. MyHomePage is defined below (title is the parameter passed in).); }}// The following code can also be directly merged with the above code, but we usually write it separately, so that it is beautiful, easy to maintain, and also reflect the idea of componentization
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);// This is used to get the parameter passed in, receiving the title above
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  The DART syntax defines the type at the first assignment and cannot be converted, unlike js, which can be changed at will
  // You can use var to define a variable, but the type is automatically defined when the variable is first assigned
  int _counter = 0;

  // write a function of your own
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // Top title bar, title is the received parameter
      appBar: AppBar(
        title: Text(widget.title),
      ),
      / / the main body
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      // This is the hover button
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,// Bind events
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
      // Bottom navigation
      bottomNavigationBar: BottomAppBar(
        color: Colors.white,
        child: Row(
          children: [
            IconButton(icon: Icon(Icons.home)),
            IconButton(icon: Icon(Icons.business)),
          ],
          mainAxisAlignment: MainAxisAlignment.spaceAround, // Divide the horizontal space of the bottom navigation bar evenly),),); }}Copy the code

Components? Is everything part of flutter?

I’m not going to cover all of them, but just a few that we usually use when we’re developing (actually, when I’m developing myself).

Basic components (a few simple and common ones)

This refers to components that can be displayed (in my opinion), such as text (not directly like on the Web), images, etc. And this is not all types, want to see the specific please see the official website or Baidu

The text

The most basic method of use

Text('I am the simplest text'),
Text(
  'I am the middle text',
  textAlign: TextAlign.center, // This is centered relative to its position (not relative to the screen). If the width of its position becomes wider, its position will change. I'm using the ListView (as described below).
),
Text(
  'I'm text with a line limit' * 9,
  maxLines: 1.// Maximum number of rows
  overflow: TextOverflow.ellipsis,// How to display when exceeding
),
Copy the code

Text add style

Text(
  'I'm styled text',
  style: TextStyle(
    backgroundColor: Colors.blue, // The background color of Colors is the official color
    color: Color.fromRGBO(100.100.100.1), Opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity: opacity
    fontSize: 15,
    height: 15.// This property is used to specify the row height, but it is not an absolute value, but a factor, which is equal to fontSize*height
    decoration: TextDecoration.lineThrough,// underline, underline, etc
    decorationStyle: TextDecorationStyle.dashed,// The style of the property above, solid line, dashed line, etc),Copy the code

A Text uses multiple styles

Text.rich(
  TextSpan(
    children: [
      TextSpan(text: "The first style"),
      TextSpan(
        text: "The second model",
        style: TextStyle(color: Colors.blue),
      ),
    ],
  ),
)
Copy the code

button

RaisedButton(
  child: Text("I'm a simple button."),
  onPressed: () {},
),
IconButton(
  icon: Icon(Icons.thumb_up),
  onPressed: () {},
),
RaisedButton.icon(
  / / the other style is almost a change of name RaisedButton/OutlineButton/FlatButton
  icon: Icon(Icons.account_balance_wallet),
  label: Text("Icon + text"),
  onPressed: () {},
),
FlatButton(
  color: Colors.blue,
  highlightColor: Colors.green[700],
  colorBrightness: Brightness.dark, // Button theme dark or light color
  splashColor: Colors.grey,
  child: Text("No icon customization"),
  shape: RoundedRectangleBorder(/ / shape
    borderRadius: BorderRadius.circular(20.0),/ / the rounded
  ),
  onPressed: () {},
),
FlatButton.icon(
  color: Colors.blue,
  icon: Icon(Icons.thumb_up),
  highlightColor: Colors.blue[700],
  colorBrightness: Brightness.dark,
  splashColor: Colors.grey,
  label: Text("With icon custom"),
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(20.0),
  ),
  onPressed: () {},
)
Copy the code

Photo/icon

Image(
  image: AssetImage('images/demo/img1.jpg'),// Why do I write this way
  width: 100.0,
),
Image.asset(
  // same as above
  "images/demo/img2.jpg",
  width: 100.0,
),
Image.network(
  // Reference network
  'https://cdn.jsdelivr.net/gh/flutterchina/[email protected]/images/flutter-mark-square-100.png',
),
Icon(Icons.home),
Icon(
  Icons.home,
  color: Colors.blueAccent,
  size: 100,),Copy the code

The usage of the image here is different from that of our web reference path, which needs to be defined in the configuration file first

The official story

Input box

TextField(
  autofocus: false.// Whether there is auto focus
  keyboardType: TextInputType.number, // Input box form text, numbers, etc
  onChanged: (value) {
    print(value);
    // Assign},),Copy the code

There are too many styles, so I won’t mention them here. There is no complete button for the number input box on ios. The solution is in my other articleDiary of Flutter trampling pitsThere’s a solution in there

The container? Where’s my div?

Container(Isn’t that the div I want?)

A Container, as its name suggests, is a Container for storing your other components (text, images, etc.), which itself has no special meaning (like our div, so to speak). Of course, it is certainly used for more than just components; it defines other properties, such as borders and backgrounds.

The simplest, simplest example

Container(
    child: Text('My parent is a Container Container.'),),Copy the code

Okay, that’s all container said. How can that be? This is my favorite, and I use it the most in development.

Container(
  width: 100,
  height: 100.// margin: EdgeInsets. All (10),// margin: EdgeInsets. All (10),// margin: EdgeInsets
  // margin: EdgeInsets. Only (left: 200, top: 20), // margin: EdgeInsets
  margin: EdgeInsets.fromLTRB(10.20.30.40), // This is four
  padding: EdgeInsets.all(10), // Inner margin, as above
  // color: Colors. BlueAccent, // Background color, remember that this will conflict with the color inside the decoration, if there is a decoration, you need to set it inside the decoration, not outside
  // foregroundDecoration: BoxDecoration(// Also decoration, but will be painted on top of the child, that is, will cover the child (rarely used)
  // color: Colors.blue,
  // ),
  decoration: BoxDecoration(
    color: Colors.greenAccent, / / the background color
    border: Border.all(color: Colors.blueAccent, width: 5), / / all
    // border: Border(
    // Top: BorderSide(color: Colors. PinkAccent, width: 5),// Single
    // right: BorderSide(color: Colors.blueAccent, width: 5),
    // ),
    borderRadius: BorderRadius.all(
      / / all
      Radius.circular(10),),// borderRadius: borderRadius. Only (// Single
    // topLeft: Radius.circular(10),
    // bottomRight: Radius.circular(20),
    // ),
    // gradient: LinearGradient(
    // // Background gradient
    // colors: [Colors.red, Colors.green, Colors.blue],
    // ),
    boxShadow: [
      BoxShadow(
        color: Colors.pinkAccent,
        blurRadius: 25.0.// Extend the distance, there will be a blur effect
        offset: Offset(10.0.5.0), // The X-axis offset is the Y-axis offset
        spreadRadius: 9.0.// Extend the distance, no blur effect
      )
    ],
  ),
  child: Text('text'), / / child elements
),
Copy the code

Because there are so many different things on display here, I’ll just put one final one.

Layout components? What’s this?

Each component of a layout class contains one or more child components. Each component of a layout class has a different layout for the child components.

Row/Column/Expanded(flex???)

Or as the name suggests, a typical row layout

Overflow cases are not mentioned here (highlight), because overflow problems need to use other components (scroll components), please be patient if you have overflow cases.

Row
Row(
  mainAxisSize:MainAxisSize.max,// The space occupied by Row in the main axis (where the main axis of Row is horizontal and Column is vertical),
  mainAxisAlignment: MainAxisAlignment.start,// The alignment of the child components on the main axis (same above) does not make sense when mainAxisSize is min
  verticalDirection:VerticalDirection.down,// Specifies the alignment of the vertical axis of the Row. The default is verticaldirection. down, which indicates from top to bottom
  crossAxisAlignment:CrossAxisAlignment.start,// The alignment of the child components on the secondary axis (row is what I prefer to call it) (iagain), as can be seen when I
  textDirection: TextDirection.ltr,// Child component layout order LTR means left-start layout (default), RTL means right-start layout
  children: <Widget>[
    Text('Row layout'),
    RaisedButton(
      child: Text("I'm a simple button."),
      onPressed: () {},
    ),
    Image(
      image: AssetImage('images/demo/img1.jpg'),
      width: 100.0,
    ),
    Image(
      image: AssetImage('images/demo/img1.jpg'),
      width: 100.0,),),Copy the code

Column

This is essentially the same thing as a row layout, but in a vertical direction, remember that the main axis of a Column is vertical, and the secondary axis is horizontal

Column(
  mainAxisSize: MainAxisSize.max,
  mainAxisAlignment: MainAxisAlignment.end,// I've changed the argument to the row layout above
  crossAxisAlignment: CrossAxisAlignment.center,// I've changed the argument to the row layout above
  textDirection: TextDirection.ltr,
  children: <Widget>[
    Text('Column layout'),
    RaisedButton(
      child: Text("I'm a simple button."),
      onPressed: () {},
    ),
    Image(
      image: AssetImage('images/demo/img2.jpg'),
      width: 100.0,
    ),
    Image(
      image: AssetImage('images/demo/img2.jpg'),
      width: 100.0,),),Copy the code

Expanded

This is because I thought that Flutter was perfect, so I just moved here.

If a Row is nested within a Row, or a Column is nested within a Column, then only the outermost Row or Column will take up as much space as possible, and the inner Row or Column will take up the actual amount of space

Container(
  color: Colors.green,
  child: Padding(
    padding: const EdgeInsets.all(16.0),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisSize: MainAxisSize.max, // The outer Colum height is the entire screen
      children: <Widget>[
        Container(
          color: Colors.red,
          child: Column(
            mainAxisSize: MainAxisSize.max,// The inner Colum height is the actual height
            children: <Widget>[
              Text("hello world "),
              Text("I am Jack "() [() [() [() [() [() [()Copy the code

If you want the inside Column to fill the outside Column, you can use Expanded components

Expanded( 
  child: Container(
    color: Colors.red,
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center, // Align vertically in the center
      children: <Widget>[
        Text("hello world "),
        Text("I am Jack "(), [(), (), (Copy the code

Stack/Positioned

This seems to me to be a bit like the parent and child in our Web development. The flutter doesn’t seem to be positioned relative to the screen (for example, our position:fixed). Remember that c-21 needs to be Positioned with Stack.

Stack(
  alignment: AlignmentDirectional
      .bottomStart, // This parameter determines how to position the child which has no positioning (no use of positioning) or partial positioning
  overflow: Overflow
      .visible, // This property determines how to display overflow.clip (clip/hide) overflow.visible (visible) child components that exceed the Stack display space.
  textDirection: TextDirection.ltr, // This has the same layout as row
  fit: StackFit.loose,// This parameter is used to determine how the unlocated subcomponent fits the Stack size. Loose indicates the size of the subcomponent, and expand indicates the size of the Stack.
  children: <Widget>[
    Positioned(
      top: 100.// Stack positioning
      left: 10,
      width: 100,
      height: 100,
      child: Container(
        color: Colors.blueAccent,
      ),
    ),
    Positioned(
      // If the position is the same, the component written in the back overwrites the previous component, with blue on the top and pink on the other, but only pink can be seen
      top: 100,
      left: 10,
      width: 100,
      height: 100,
      child: Container(
        color: Colors.pinkAccent,
      ),
    ),
    Positioned(
      // Cover the top half
      top: 150,
      left: 10,
      width: 100,
      height: 100,
      child: Container(
        color: Colors.orangeAccent,
      ),
    ),
    Container(
      color: Colors.greenAccent,
      child: Text('I didn't set the location'),),),Copy the code

The difference between visible and hidden That’s all for layout components, and if you need other layout components, you can directly see the official website or Baidu.

Rolling components? Won’t it move on its own? Overflow? What the hell? Doesn’t it hide itself?

I wanted to talk about spillover separately, but I thought it would be better to talk about spillover together.

Let’s start with an overflow. When we set a child component that is out of the screen (for example, I set a lot of images on the row component, as shown below), we call it an overflow.That’s because it doesn’t move on its own (if you think it’s yellow because you have yellow eyes)… That’s when we need to get it moving.

ListView

The easiest way to write this is because what we use in development is to get data from the interface and not know how many

ListView(
  scrollDirection: Axis.vertical, // Scroll direction
  padding: EdgeInsets.all(20.0), / / padding
  // itemExtent:10,
  // shrinkWrap: true,// This property indicates whether to set the ListView length based on the total length of child components. The default is false. By default, the ListView takes up as much space as possible in the scrolling direction. When the ListView is in an unbounded (scroll direction)
  children: <Widget>[
    Container(
      height: 150,
      color: Colors.pinkAccent,
    ),
    Container(
      height: 150,
      color: Colors.greenAccent,
    ),
    Container(
      height: 150,
      color: Colors.blueAccent,
    ),
    Container(
      height: 150,
      color: Colors.black54,
    ),
    Container(
      height: 150,
      color: Colors.orangeAccent,
    ),
    Container(
      height: 150,
      color: Colors.cyanAccent,
    ),
  ],
),
Copy the code

More advanced writing, dynamic generation

import 'package:flutter/material.dart';

class ListViewDemo extends StatefulWidget {
  @override
  _ListViewDemoState createState() => _ListViewDemoState();
}

class _ListViewDemoState extends State<ListViewDemo>
    with SingleTickerProviderStateMixin {
  // Define an array
  List list = [
    {'name': '1'},
    {'name': '2'},
    {'name': '3'},
    {'name': '4'},
    {'name': '5'},
    {'name': '6'},
    {'name': '7'},];@override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Scroll component ListView'),
        centerTitle: true,
      ),
      body: ListView.builder(
        itemCount: list.length, // Array length
        itemBuilder: (context, index) {// Context and index
          return Container(// Return a container component
            height: 150,
            color: Color.fromRGBO(200.200, index * 30.1),// Here I am in order to better distinguish
            child: Text(list[index]['name'])); },),); }}Copy the code

GridView

This one is pretty much the same as the one above, so I won’t talk too much about it.

import 'package:flutter/material.dart';

class GridViewDemo extends StatefulWidget {
  @override
  _GridViewDemoState createState() => _GridViewDemoState();
}

class _GridViewDemoState extends State<GridViewDemo>
    with SingleTickerProviderStateMixin {
  List list = [
    Icons.ac_unit,
    Icons.airport_shuttle,
    Icons.all_inclusive,
    Icons.tag_faces,
    Icons.beach_access,
    Icons.cake,
    Icons.free_breakfast,
  ];

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Grid scrolling GridView'),
        centerTitle: true,
      ),
      body: GridView.builder(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3,
          childAspectRatio: 1.0,
        ),
        itemCount: list.length,
        itemBuilder: (context, index) {
          // return Text(list[index].toString()+'222');
          returnIcon(list[index]); },),// GridView(
      // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
      // crossAxisCount: 3, // three child widgets on the horizontal axis
      ChildAspectRatio: 1.0 childAspectRatio: 1.0 childAspectRatio: 1.0 Since crossAxisCount is specified, the length of the child along the axis is determined, and then the length of the child along the axis is determined by this parameter value
      / /),
      // children: 
      
       [
      
      // Icon(Icons.ac_unit),
      // Icon(Icons.airport_shuttle),
      // Icon(Icons.all_inclusive),
      // Icon(Icons.beach_access),
      // Icon(Icons.cake),
      // Icon(Icons.free_breakfast)
      / /,
      // ),
      // gridview.count (// it is the same as above
      // crossAxisCount: 3,
      / / childAspectRatio: 1.0.
      // children: 
      
       [
      
      // Icon(Icons.ac_unit),
      // Icon(Icons.airport_shuttle),
      // Icon(Icons.all_inclusive),
      // Icon(Icons.beach_access),
      // Icon(Icons.cake),
      // Icon(Icons.free_breakfast),
      / /,
      // ),); }}Copy the code

Advanced knowledge (this will be added gradually, HTTP request encapsulation should be next)

Routing? How do I manage route configuration?

Instead of navigator.pushnamed (context, ‘/ path ‘), this is a unified route configuration.

The first is configured directly in the entry file

import 'package:flutter/material.dart';

/* Import the page */
import './page/homePage.dart';
import './page/404.dart';
/* demo */
import './demo/index.dart';
import './demo/text.dart';
import './demo/button.dart';
import './demo/imgAndIcon.dart';
import './demo/input.dart';
import './demo/container.dart';
import './demo/row.dart';
import './demo/column.dart';
import './demo/stackPositioned.dart';
import './demo/listView.dart';
import './demo/gridView.dart';
import './demo/customScrollView.dart';

/* Define the routing path */
final routes = {
  '/': (context) => MyHomePage(),
  '/notFind': (context) => NotFind(),
  /* demo */
  '/demoEntry': (context) => DemoEntry(),
  '/textDemo': (context, {arguments}) => TextDemo(),
  '/buttonDemo': (context, {arguments}) => ButtonDemo(),
  '/imgAndIcon': (context, {arguments}) => ImgAndIcon(),
  '/inputDemo': (context, {arguments}) => InputDemo(),
  '/containerDemo': (context, {arguments}) => ContainerDemo(),
  '/rowDemo': (context, {arguments}) => RowDemo(),
  '/columnDemo': (context, {arguments}) => ColumnDemo(),
  '/stackPositionedDemo': (context, {arguments}) => StackPositionedDemo(),
  '/listViewDemo': (context, {arguments}) => ListViewDemo(),
  '/gridViewDemo': (context, {arguments}) => GridViewDemo(),
  '/customScrollViewDemo': (context, {arguments}) => CustomScrollViewDemo(),
};

/* Route interception (where you can handle route parameters, etc.) */
Function onGenerateRoute = (RouteSettings settings) {
  final String routeName = settings.name;
  final Function buildContext = routes[routeName];
  Route route;
  print(buildContext);
  if(buildContext ! =null) {
    // If the route exists
    if(settings.arguments ! =null) {
      // If there is a route pass parameter
      route = MaterialPageRoute(
          builder: (context) =>
              buildContext(context, arguments: settings.arguments));
    } else{ route = MaterialPageRoute(builder: (context) => buildContext(context)); }}else {
    // Route does not exist to jump to the specified page
    route =
        MaterialPageRoute(builder: (context) => routes['/notFind'](context));
  }
  return route;
};

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      routes:
          routes, // Add onGenerateRoute (routes); // Add onGenerateRoute (routes)
      onGenerateRoute: onGenerateRoute,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      initialRoute: '/'.// Inbound routing); }}Copy the code

The second route configuration file (recommended)

It is better to put the route in another file for easy management, we just need to import the route file in the main entry file. The router. The dart files

import 'package:flutter/material.dart';
import '.. /page/homePage.dart';
import '.. /page/404.dart';

/* demo */
import '.. /demo/index.dart';
import '.. /demo/text.dart';
import '.. /demo/button.dart';
import '.. /demo/imgAndIcon.dart';
import '.. /demo/input.dart';
import '.. /demo/container.dart';
import '.. /demo/row.dart';
import '.. /demo/column.dart';
import '.. /demo/stackPositioned.dart';
import '.. /demo/listView.dart';
import '.. /demo/gridView.dart';
import '.. /demo/customScrollView.dart';

final routes = {
  '/': (context) => MyHomePage(),
  '/notFind': (context) => NotFind(),
  /* demo */
  '/demoEntry': (context) => DemoEntry(),
  '/textDemo': (context, {arguments}) => TextDemo(),
  '/buttonDemo': (context, {arguments}) => ButtonDemo(),
  '/imgAndIcon': (context, {arguments}) => ImgAndIcon(),
  '/inputDemo': (context, {arguments}) => InputDemo(),
  '/containerDemo': (context, {arguments}) => ContainerDemo(),
  '/rowDemo': (context, {arguments}) => RowDemo(),
  '/columnDemo': (context, {arguments}) => ColumnDemo(),
  '/stackPositionedDemo': (context, {arguments}) => StackPositionedDemo(),
  '/listViewDemo': (context, {arguments}) => ListViewDemo(),
  '/gridViewDemo': (context, {arguments}) => GridViewDemo(),
  '/customScrollViewDemo': (context, {arguments}) => CustomScrollViewDemo(),
};

/* Route interception */
Function onGenerateRoute = (RouteSettings settings) {
  final String routeName = settings.name;
  final Function buildContext = routes[routeName];
  Route route;
  // print(buildContext);
  if(buildContext ! =null) {
    if(settings.arguments ! =null) {
      route = MaterialPageRoute(
          builder: (context) =>
              buildContext(context, arguments: settings.arguments));
    } else{ route = MaterialPageRoute(builder: (context) => buildContext(context)); }}else {
    route =
        MaterialPageRoute(builder: (context) => routes['/notFind'](context));
  }
  return route;
};
Copy the code

Main entry file

import 'package:flutter/material.dart';
import './router/router.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false.// routes: routes,
      onGenerateRoute: onGenerateRoute,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      initialRoute: '/',); }}Copy the code

The second one looks a lot better

HTTP request encapsulation (not yet, work in progress)

teasing

Including environment installation (or in their own games on the computer installed these), write demo, and so on, before and after also made a fast day of time (may be I too rubbish), so feel the article a little help, please give a thumb-up!!

Feel the article too waste, beg to give a point of opinion, thank you

Attached here is another article I wrote about Flutter Stomp Diary and github address