The author | NiuZhaoJie guest (clothing)

Edit | orange

New retail product | alibaba tao technology

In the past two years, Flutter has become more and more popular. No matter in Alibaba or outside companies, more and more people are involved in Flutter ecological construction. Flutter serves as a cross-terminal UI framework, and has the potential to be a DSL like Rax for building pages for intra-group marketing campaigns. Therefore, it is fashionable and valuable to learn about Flutter and participate in the ecological construction of Flutter.

What is the Flutter

Flutter is Google’s mobile UI framework for quickly building high-quality native user interfaces on iOS and Android. Flutter can work with existing code. Flutter is being used by more and more developers and organizations around the world, and Flutter is completely free and open source. To put it simply, Flutter is a mobile app SDK that contains frameworks, controls, and tools to build both Android and iOS apps with a single set of code that performs as well as native apps. Introduction of Flutter

Configuring the Development Environment

Flutter development can be done on macOS, Linux, or Windows. While you can use any editor in the Flutter toolchain, IDE plug-ins for IntelliJ IDEA, Android Studio, and Visual Studio Code simplify development.

  • Download the Flutter SDK. [address] (flutterchina. Club/get started…

)

  • Add the bin directory of flutter to the path.

  • Execute the Flutter doctor command, which will install the Flutter framework, including dart, and alert you to any other dependencies that need to be installed.

  • Install other dependencies.

  • Install the Flutter plugin in the IDE.

experience

Android Studio (Full IDE experience for Flutter)

Create an

  • Select File>New Flutter Project

  • Select Flutter Application as the Project type and click Next

  • Enter a project name, such as MyApp, and click Next

  • Click Finish

  • Wait for Android Studio to install the SDK and create the project. In the project directory, the code for your application is located in lib/main.dart.

Run the application

Navigate to the Android Studio toolbar:

  • In target Selector, select an Android device running the application. If not listed, choose Tools>Android>AVD Manager and create one there
  • Click the Run icon in the toolbar, or invoke the menu item Run > Run.

VS Code(lightweight editor for Flutter running and debugging)

Create an

  • Start VS Code.
  • Call the View > Command Palette…
  • Enter ‘flutter’ and select ‘flutter: New Project’ action
  • Enter a Project name, such as MyApp, and press Enter
  • Specify where to place the item, and then press the blue OK button
  • Wait for the project creation to continue and display the main.dart file in the project directory, with your application’s code in lib/main.dart.

Run the application

  • Make sure the target device is selected in the lower right corner of VS Code
  • Press F5 or call Debug>Start Debugging
  • Wait for the application to start

Terminal + editor

Create an

Create a project with flutter create

$ flutter create myapp
$ cd myapp
Copy the code

Run the application

Check whether the Android device is running. If no, refer to Settings.

$ flutter devices
Copy the code

Run the flutter run command to run the application:

$ flutter run
Copy the code

If all is well, you should see the application launched on your device or emulator:

The project structure

┬ ├ projectName ┬ ├ Android - Android Part Of the project ├ Build - Project Build directory ├ ios-ios part of the project ├ lib - Project Dart source file ┬ ├ SRC - ├ test - Test related file ├ pubspec.yaml - Project dependency configuration file similar to RN's package.jsonCopy the code

How do I add the dependencies needed for a Flutter project?

  • In Android, you can add dependencies in Gradle files.
  • In iOS, it’s common to add dependencies to your Podfile;
  • In RN, project dependencies are typically managed by package.json;

Flutter uses the Dart build system and the Pub package manager to handle dependencies. These tools delegate the build of Android and iOS Native wrapped applications to the appropriate build system.

Dependencies: flutter: SDK: flutter Google_sign_in: ^3.0.3Copy the code

In Flutter, although there are Gradle files under the Android folder in the Flutter project, these files are only used to add the required platform-specific dependencies. Otherwise, pubspec.yaml should be used to declare external dependencies for Flutter.

The same is true for iOS. If you have podfiles in the iOS folder of your Flutter project, use them only to add iOS platform-specific dependencies. Otherwise, pubspec.yaml should be used to declare external dependencies for Flutter.

How do I archive image resources and deal with different resolutions

  • Although Android treats resources and assets differently, they are treated as assets in Flutter. All resources that exist in the Res /drawable- * folder on Android are placed in the assets folder of Flutter.

  • Similar to Android, iOS also treats images and assets as different things, while Flutter only has assets. Assets placed in iOS images.xcasset are placed in assets in Flutter.

Assets can be any type of file in Flutter, not just images. For example, you can place json files in your my-Assets folder.

my-assets/data.json
Copy the code

Remember to declare assets in the pubspec.yaml file:

assets:
 - my-assets/data.json
Copy the code

Then in code we can access it via AssetBundle:

import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;

Future<String> loadAsset() async {
  return await rootBundle.loadString('my-assets/data.json');
}
Copy the code

For images, Flutter, like iOS, follows a simple format based on pixel density. Image assets may be 1.0x 2.0x 3.0x or any other multiple. This devicePixelRatio represents the ratio of physical pixels to a single logical pixel.

The relation between Android images with different pixel densities and the pixel ratios of Flutter

Ldpi 0.75x MDPI 1.0x HDPI 1.5x xhdPI 2.0x xxHDPI 3.0x xxxHDPI 4.0xCopy the code

For example, to put an image named my_icon. PNG into the Flutter project, you might want to put it in the images folder. Place the image (1.0x) in the images folder, and place other resolution images in their respective subfolders with appropriate scaling factors, like this:

Images /my_icon. PNG // Base: 1.0x image images/2.0x/my_icon. PNG // 2.0x image images/3.0x/my_icon. PNG // 3.0x imageCopy the code

You can then declare the image resource in the pubspec.yaml file as follows:

assets:
 - images/my_icon.png
Copy the code

Now we can access it with AssetImage.

return AssetImage("images/a_dot_burr.jpeg");
Copy the code

Also available directly from the Image Widget:

@override
Widget build(BuildContext context) {
  return Image.asset("images/my_image.png");
}
Copy the code

How do I archive strings resources and how do I deal with different languages?

Unlike iOS, which has a Localizable. Strings file, Flutter does not currently have a dedicated string resource system. Currently, the best practice is to keep the Strings resource as a static field in the class. Such as:

class Strings {
  static String welcomeMessage = "Welcome To Flutter";
}
Copy the code

Then access it as follows:

Text(Strings.welcomeMessage)
Copy the code

By default, Flutter supports only American English strings. If you want to support other languages, introduce the Flutter_localIzations package. You may also want to introduce intL packages to support other I10N mechanisms, such as date/time formatting.

dependencies:
  # ...
  flutter_localizations:
    sdk: flutter
  intl: "^0.15.6"
Copy the code

To use the Flutter_localizations package localizationsDelegates and supportedLocales also need to be specified in the app Widget.

import 'package:flutter_localizations/flutter_localizations.dart'; MaterialApp( localizationsDelegates: [ // Add 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 ], / /...).Copy the code

These proxies include the actual localized values, and supportedLocales define which locales are supported by the App. The above example USES a MaterialApp, so it has both GlobalWidgetsLocalizations basis for widgets, There also MaterialWidgetsLocalizations for Material wigets localization. If you’re using WidgetsApp, you don’t need to include the latter. Note that both agents include “default” values, but if you want to localize your App, you still need to provide one or more agents as copies of your App localization.

When initialized, WidgetsApp or MaterialApp will create a Localizations Widget for you using your specified proxy. The Localizations Widget allows you to access the location of the device from the current context at any time, or using window.locale.

To access the localization file, use the Localizations.of() method to access the specific localization class that provides the proxy. If translation is required, use the INTl_translation package to extract the translation copy into the ARB file. Import them into your App and use them with INTL.

For more details on internationalization and localization in Flutter, visit the Internationalization Guide, which has sample code for not using INTL packages.

component

Everything in Flutter is a component. There are more than 350 subclasses of widgets and indirect subclasses alone. Do you really need to learn more than 350 components if you want to learn them? There is a famous law of 80/20 in economics, and we learn Flutter also applies to the 80/20 law. Most of the components of Flutter are rarely used, so as a beginner, you only need to learn the 20% of components that are commonly used.

RenderObjectWidget and its subclasses are 89:

There are 34 ProxyWidgets and their subclasses:

There are 89 StatelessWidgets and their subclasses:

StatefulWidget has the most subclasses, up to 141

The component tree

When Flutter creates an App, all the components will eventually generate a component tree, as shown in the following code:

void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( ), home: Scaffold( body: Text('Hello world! '),),); }}Copy the code

The main function is where the application starts, running the MyApp component. The generated component tree is as follows:

Center the Text component as follows:

Scaffold( body: Center( child: Text('Hello world! '),),)Copy the code

Add an AppBar to your application:

Scaffold( appBar: AppBar(), body: Center( child: Text('Hello world! '),),)Copy the code

StatefulWidget vs StatelessWidget

Flutter components are classified into stateless widgets and stateful widgets. The only difference is how the component is reloaded at run time. The StatelessWidget component reloads to create an instance of the current component, while the StatefulWidget component reloads not to create the instance but to re-execute the build function.

How the StatelessWidget component is created:

class StatelessWidgetDemo extends StatelessWidget { @override Widget build(BuildContext context) { return Container(); }}Copy the code

The build function returns the current component, which is immutable once created and can only be executed once. If you want to redraw this component, you can only recreate a new instance of the component.

How StatefulWidget components are created:

class StatefulWidgetDemo extends StatefulWidget { @override _StatefulWidgetDemoState createState() => _StatefulWidgetDemoState(); } class _StatefulWidgetDemoState extends State<StatefulWidgetDemo> { @override Widget build(BuildContext context) { return Container(); }}Copy the code

The StatefulWidget component is created differently from the StatelessWidget in that the build function in State<> returns the current component, and a stateful component can be redrawn multiple times over its lifetime by calling the Build function multiple times instead of creating a new instance.

The setState method is called to redraw the StatefulWidget component. Setstate will redraw itself and its child components. Therefore, try to encapsulate the StatefulWidget component to avoid invalid reconstruction and redrawing, which may affect performance.

Quick writing tips: You can quickly create StatelessWidget components by typing STL in Android Studio and VS Code and hitting Enter. Similarly, you can quickly create StatefulWidget components by typing STF and hitting Enter. This is what the editor Live Templates does.

Material vs Cupertino

There are two styles of Flutter components: Material and Cupertino. Cupertino is an ios-style component named with the Cupertino prefix. Like cupertino oslider and CupertinoDatePicker, Material Design was created by Google to provide a more consistent and extensive “look and feel” for mobile phones, tablets, desktops and “other platforms.”

Flutter uses a set of codes to behave consistently across platforms. It does not draw different shapes for different platforms, such as using AlertDialog to pop up warning boxes. Flutter works equally well on Android and iOS.

But there are some features that Flutter distinguishes platforms. For example, the ListView slides to the bottom, and Android has a light blue (by default) arch at the bottom that iOS does not. This is because Flutter distinguishes platforms in code when it encapsulates this component. Therefore, if you look at the Flutter source code, you will often see that different processes are made for different platforms.

conclusion

The cost of learning about Flutter is mainly in getting familiar with the components. If you are familiar with the common components, you can start the project. As for other controls, you only need to browse briefly and remember that Flutter already provides this component when you encounter some features while working on a project.