Introduction

In order to simplify everyone's use, although flutter recommends that all widgets be built by themselves, on the large framework, flutter provides a collection of Widgets in two theme styles, Material and Cupertino. You can carry out the inheritance of these two styles. Personalization and development.

The two styles translated into Chinese are: Material and Cupertino? What the hell....let's call them by their default English names.

In this article, we will dive into the basics of the Material theme - MaterialApp.

A Preliminary Study of MaterialApp

If you use the latest android studio to create a flutter project, android studio will automatically create a flutter based app for you.

Let's take a look at the automatically created main.dart file:

 Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    )
  }

The widget returned by the build method is the root widget of the flutter application. As you can see, a MaterialApp is returned by default.

In the sample code above, the tile, theme and home properties are set for MaterialApp.

title is the title of MaterialApp, theme is the theme of the entire MaterialApp, and home represents the main page that should be displayed when the app enters.

By default MyHomePage will return a Scaffold similar to the following code:

 return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: const <Widget>[
            Text(
              'home page',
            ),
          ],
        ),
      ),
    );

In this way, we can get the common MaterialApp interface:

MaterialApp details

With the above framework, we can build our own components in our home and start a happy app journey of flutter.

So what other functions does MaterialApp have? What is the underlying principle of it? Let's take a look together.

First is the definition of MaterialApp:

 class MaterialApp extends StatefulWidget

It can be seen that MaterialApp is a StatefulWidget, which means that MaterialApp may rebuild sub-components according to the user's input. Generally speaking, MaterialApp represents an application as a whole, so it needs to consider many complex interaction situations. It is reasonable to use StatefulWidget. .

theme in MaterialApp

Next, let's take a look at the themes that MaterialApp can configure.

There are the following themes in MaterialApp:

 final ThemeData? theme;

  final ThemeData? darkTheme;

  final ThemeData? highContrastTheme;

  final ThemeData? highContrastDarkTheme;

  final ThemeMode? themeMode;

ThemeData is used to define the theme style of widget. ThemeData includes colorScheme and textTheme.

For the sake of simplicity, flutter provides two concise Theme creation methods, ThemeData.light and ThemeData.dark. Of course you can also use ThemeData.from to create new themes from ColorScheme.

So the question is, why does an app have so much ThemeData?

By default, the theme is the theme that the app will use, but considering the current popular theme switching, the darkTheme option is also provided.

If both theme and darkTheme are set, then which theme to use will be determined according to themeMode.

Note that the default theme is ThemeData.light()

The existence of highContrastTheme and highContrastDarkTheme is also because in some systems high contrast and dark theme versions are required, and these ThemeData are optional.

The themeMode field, if you take ThemeMode.system, then the system theme configuration will be used by default. Specifically, it is called MediaQuery.platformBrightnessOf to query whether the system is Brightness.light or Brightness.dark.

Although the default is ThemeMode.system, you can also specify it as ThemeMode.light or ThemeMode.dark.

routes in MaterialApp

Like the home page of a web page, in MaterialApp, we also need to define some routing information for page jumps.

Before explaining routes, we need to understand that there are two definitions related to routing in flutter, namely routes and Navigator.

Where routes is the definition of a route, which represents the widget addresses corresponding to different paths, such as the following definition of routers:

 routes: <String, WidgetBuilder> {
       '/a': (BuildContext context) => MyPage(title: 'page A'),
       '/b': (BuildContext context) => MyPage(title: 'page B'),
       '/c': (BuildContext context) => MyPage(title: 'page C'),
     },

The type of routers is Map<String, WidgetBuilder>, the corresponding key is the routing address, and the value is the WidgetBuilder corresponding to the routing address.

Navigator is a Widget used to manage routers.

Navigator can manage routers by using Navigator.pages, Navigator.push or Navigator.pop. for example:

push:

 Navigator.push(context, MaterialPageRoute<void>(
   builder: (BuildContext context) {
     return Scaffold(
       appBar: AppBar(title: Text('My Page')),
       body: Center(
         child: TextButton(
           child: Text('POP'),
           onPressed: () {
             Navigator.pop(context);
           },
         ),
       ),
     );
   },
 ));

pop:

 Navigator.pop(context);

For MaterialApp, if it is the / route, then the Widget corresponding to the home attribute in the MaterialApp will be searched. If the Widget corresponding to the home does not exist, the configuration in the routers will be used.

If none of the above information is available, it means that a router needs to be created, and the onGenerateRoute method will be called to create a new router.

So onGenerateRoute is used to handle routes that are not defined in the home and routers methods. You can also think of it as a way to create dynamic routes.

Finally, if none of the route rules match, onUnknownRoute is called.

If home, routes, onGenerateRoute, onUnknownRoute are all empty, and builder is not empty, then no Navigator will be created.

locale in MaterialApp

What is local? Local represents a language in internationalization. By using Local, you do not have to hardcode the text to be displayed in the program, so as to achieve the internationalization support of APP.

local in dart can be used like this:

 const Locale swissFrench = Locale('fr', 'CH');
const Locale canadianFrench = Locale('fr', 'CA');

In MaterialApp, both localizationsDelegates and supportedLocales need to be configured:

 MaterialApp(
  localizationsDelegates: [
    // ... app-specific localization delegate[s] here
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
  ],
  supportedLocales: [
    const Locale('en', 'US'), // English
    const Locale('he', 'IL'), // Hebrew
    // ... other locales the app supports
  ],
  // ...
)

The supported locales are configured in supportedLocales, and localizationsDelegates are used to generate WidgetsLocalizations and MaterialLocalizations.

For the specific use of locale, you can pay attention to the follow-up articles.

MaterialApp and WidgetsApp

MaterialApp is a StatefulWidget, so the State bound to it is called: _MaterialAppState, there is a build method in _MaterialAppStatez, what exactly is the returned widget?

 return ScrollConfiguration(
      behavior: widget.scrollBehavior ?? const MaterialScrollBehavior(),
      child: HeroControllerScope(
        controller: _heroController,
        child: result,
      ),
    );

As you can see, what is finally returned is a ScrollConfiguration, which essentially returns a result wrapped in HeroControllerScope.

What is Hero? Hero is a component in flutter, which is used to indicate that in the process of route switching, you can fly from the old route to the new route. Such a flying animation is also called a Hero animation.

And this result is actually a WidgetsApp.

WidgetsApp is the underlying Widget of MaterialApp, which wraps many widgets that applications usually need.

One of the main functions of WidgetsApp is to bind the system back button to the popup navigator or to exit the application.

In terms of implementation, both MaterialApp and CupertinoApp use it to implement the basic functions of the application.

Summarize

MaterialApp is the first entry of Material style, I hope everyone can master its usage.

Example from this article: https://github.com/ddean2009/learn-flutter.git

For more information, please refer to http://www.flydean.com/06-flutter-material-materialapp/

The most popular interpretation, the most profound dry goods, the most concise tutorials, and many tricks you don't know are waiting for you to discover!

Welcome to pay attention to my official account: "Program those things", understand technology, understand you better!


flydean
890 声望437 粉丝

欢迎访问我的个人网站:www.flydean.com