A. Introduction of Flutter

cross-platform

Flutter aims to enable the same set of code to run on both Android and iOS systems with performance comparable to native apps.

Platforms supported by Flutter:

  1. The mobile terminal
  2. Web page
  3. Windows, Linux and macOS

A high performance

Technical types rendering performance Development efficiency dynamic On behalf of the framework
H5 + native Package native (camera, contact, device, etc.)+ WebView low high support ionic,cordova
Js + native rendering Native control rendering high In the support Weex, react native
Native + self drawing engine Skia 2D rendering engine high high no flutter

Learning resources

  1. Flutter Chinese website: FlutterChina.club /
  2. Flutter plugin: pub. Flutter – IO. Cn /
  3. Flutter control is introduced: toly1994328. Gitee. IO/flutter_web…
  4. Dart language: www.dartcn.com/
  5. Open source: Github

2. The Flutter theory

Frame structure

Flutter Framework

This is a pure Dart implementation SDK that implements a set of base libraries, from the bottom up. Let’s take a quick look at it:

  • The bottom two layers (Foundation, Animation, Painting, and Gestures) are dart UI layers that correspond to Flutterdart:uiPackage, which is the underlying UI library exposed by the Flutter engine, providing animation, gesture, and drawing capabilities.
  • The Rendering layer is the abstract layout layer and relies on the DART UI layer. The Rendering layer builds a UI tree, and when the TREE changes, it calculates the changed parts, updates the tree, and draws the TREE on the screen. The Rendering layer is the core part of the Flutter UI framework, which determines the location and size of each UI element and performs coordinate transformation and Rendering (calling the underlying DART: UI).
  • The Widgets layer is the base library provided by Flutter. On top of the base library, Flutter also provides libraries of Components in the Material and Cupertino visual styles. Most of the scenarios we’ve developed for Flutter only deal with these two layers.

Flutter engine

The SDK is a pure C++ implementation that includes the Skia engine, Dart runtime, text typesetting engine, and more. When code calls the DART: UI library, the call eventually makes its way to the Engine layer, where the actual drawing logic is implemented.

How to draw

  1. RenderObject: The base class for all nodes in the render tree that defines interfaces related to layout, drawing, and composition

  2. RendererBinding: The glue layer of the render tree and the Flutter engine that manages the monitoring of frame redrawing, window size and changes in render parameters.

  3. RenderObjectWidget#createRenderObject(BuildContext context) → RenderObject creates a different type of RenderObject for each control in the tree. Make up a tree of render objects

Iii. Mixed development

Making address:

Github.com/alibaba/flu…

Introduction: Produced by Ali

A new generation of Flutter-Native hybrid solutions. FlutterBoost is a Flutter plug-in that makes it easy to provide a Flutter hybrid integration solution for existing native applications. The idea behind FlutterBoost is to use Flutter like a Webview. Managing both Native and Flutter pages in an existing application is not easy. FlutterBoost handles the mapping and jumping of the page for you, all you need to know is the name of the page and the parameters (usually urls).

How to mix development

1. New flutterModule
2. Add pubspec.yaml plug-in
dependencies:
  flutter:
    sdk: flutter
  flutter_boost:
      git:
        url: 'https://github.com/alibaba/flutter_boost.git'
        ref: '1.17.1'
Copy the code
3. Add dependencies natively

build.gradle

implementation project(':flutter')
implementation project(':flutter_boost')
Copy the code

settings.gradle

setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir,
        'flutter_module\\.android\\include_flutter.groovy'
))


include ':flutter_module'

Copy the code
4. The application initialization
private fun initFlutter(a) {
        val router =
            INativeRouter { context, url, urlParams, requestCode, exts ->
                val assembleUrl =
                    Utils.assembleUrl(url, urlParams)
                PageRouter.openPageByUrl(context, assembleUrl, urlParams)
            }

        val boostLifecycleListener: BoostLifecycleListener = object : BoostLifecycleListener {
            override fun beforeCreateEngine(a) {}
            override fun onEngineCreated(a) {

                // Register MethodChannel and listen for getPlatformVersion calls on the flutter side
                val methodChannel = MethodChannel(
                    FlutterBoost.instance().engineProvider().dartExecutor,
                    "flutter_native_channel"
                )
                methodChannel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result ->
                    when (call.method) {
                        "getPlatformVersion" -> {
                            result.success(Build.VERSION.RELEASE)
                        }
                        "getPlatformChannel" -> {
                            result.success(BuildConfig.FLAVOR)
                        }
                        "getToken" -> {
                            result.success(SPUtils.getInstance().getString(Constants.Access_Token))
                        }
                        else -> {
                            result.notImplemented()
                        }
                    }
                }

                // Register PlatformView viewTypeId to correspond to the viewType in the flutter
// FlutterBoost
// .instance()
// .engineProvider()
// .platformViewsController
// .registry
// .registerViewFactory(
// "plugins.test/view",
// TextPlatformViewFactory(StandardMessageCodec.INSTANCE)
/ /)
            }

            override fun onPluginsRegistered(a) {}
            override fun onEngineDestroy(a){}}//
        // Androidmanifest.xml must add the flutterEmbedding version setting
        //
        // 
        // android:value="2">
        // 
        / / GeneratedPluginRegistrant will automatically generate new way of the plug-in
        //
        // Please use the plug-in registration method
        // FlutterBoost.instance().engineProvider().getPlugins().add(new FlutterPlugin());
        / / GeneratedPluginRegistrant. RegisterWith () is executed immediately after the engine to create, radiation form calls
        //
        val platform = FlutterBoost.ConfigBuilder(this, router)
            .isDebug(true)
            .whenEngineStart(FlutterBoost.ConfigBuilder.ANY_ACTIVITY_CREATED)
            .renderMode(FlutterView.RenderMode.texture)
            .lifecycleListener(boostLifecycleListener)
            .build()
        FlutterBoost.instance().init(platform)
    }
Copy the code
<meta-data android:name="flutterEmbedding"
    android:value="2">
</meta-data>

<activity
	android:name="com.idlefish.flutterboost.containers.BoostFlutterActivity"
                			     android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
            android:hardwareAccelerated="true"
            android:theme="@style/Theme.AppCompat"
            android:windowSoftInputMode="adjustResize"/>
Copy the code
5. Configure routes
class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();

    FlutterBoost.singleton.registerPageBuilders(<String, PageBuilder>{


      ///You can pass parameters in the native layer via getContainerParams
      'flutterPage': (String pageName, Map<String.dynamic> params, String _) {
        print('flutterPage params:$params');

        returnFlutterRouteWidget(params: params); }}); FlutterBoost.singleton.addBoostNavigatorObserver(TestBoostNavigatorObserver()); }@override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Boost example',
        builder: FlutterBoost.init(postPush: _onRoutePushed),
        home: Container(color: Colors.white));
  }

  void _onRoutePushed(
    String pageName,
    String uniqueId,
    Map<String.dynamic> params,
    Route<dynamic> route,
    Future<dynamic> _,) {}}Copy the code

Native configuration route

public class PageRouter {

    public final static Map<String, String> pageName = new HashMap<String, String>() {{
        put("sample://flutterPage"."flutterPage");
    }};

    public static final String NATIVE_PAGE_URL = "sample://nativePage";
    public static final String FLUTTER_PAGE_URL = "sample://flutterPage";

    public static boolean openPageByUrl(Context context, String url, Map params) {
        return openPageByUrl(context, url, params, 0);
    }

    public static boolean openPageByUrl(Context context, String url, Map params, int requestCode) {

        String path = url.split("\ \"?") [0];

        Log.i("openPageByUrl",path);

        try {
            if (pageName.containsKey(path)) {
                Intent intent = BoostFlutterActivity.withNewEngine().url(pageName.get(path)).params(params)
                        .backgroundMode(BoostFlutterActivity.BackgroundMode.opaque).build(context);
                if(context instanceof Activity){
                    Activity activity=(Activity)context;
                    activity.startActivityForResult(intent,requestCode);
                }else{
                    context.startActivity(intent);
                }
                return true;
            }else if (url.startsWith(NATIVE_PAGE_URL)) {
                String aNative = (String) params.get("native");
                Timber.e("Return:"+aNative);
                NavigationUtils.INSTANCE.goWorkStateActivity();
                return true;
            }
            return false;

        } catch (Throwable t) {
            return false; }}}Copy the code
6. Route redirection
  / / native
  val params= mutableMapOf<String,String>()
                params["test1"] = "v_test1"
                params["test2"] = "v_test2"
  //Add some params if needed.
  PageRouter.openPageByUrl(this, PageRouter.FLUTTER_PAGE_URL, params)
Copy the code
onTap: () => FlutterBoost.singleton.open(
                  'sample://nativePage'.// urlParams: 
      
       {
      ,>
// 'query': 
      
       {'native': 'bbb'}
      ,>
/ /},
                  urlParams: {"native": "I'm parameter b"},),Copy the code

4. Web development

1. The flutter SDK configuration

Find flutter_console.bat in the SDK folder

flutter channel
flutter channel beta
flutter upgrade
flutter config --enable-web
flutter devices
Copy the code

2. Install the Web compilation tool

flutter pub global activate webdev
Copy the code

Configure the environment variable: add D:\flutter\ fluttersssss. pub-cache\bin to path

Release 3.

If you want to see the release, you can run it

flutter build web
Copy the code

A package file will be generated in the project D:\flutter\flutter_web_app\build\web

5. Windows development

1. The flutter SDK configuration

Find flutter_console.bat in the SDK folder

flutter channel
flutter channel master
flutter upgrade
flutter config --enable-windows-desktop
Copy the code

2. If your computer isn’t thereDeveloper modeAn error occurs when using plug-ins. You can be inSettings --> Updates and Security --> Developer optionsSet in the

Building with plugins requires symlink support. Please enable Developer Mode in your system settings
Copy the code

3. Installed VisualStudio

Select c++ development

Exception: Unable to find suitable Visual Studio toolchain. Please run flutter doctor for more details.

Flutter Doctor check error

4. Packaging exe

flutter build windows
Copy the code

Exe D:\flutter\flutter_windows\build\ Windows \ Runner \Release will be generated in this directory

Advanced Installer is a tool that builds Windows installers

Desktop development plugin address :github.com/google/flut…

My demo address: gitee.com/hhyq520/flu…

Mobile terminal MVVM + Provider setting up environment

Please look forward to… More exciting next time

7. To summarize

1. Other platforms are immature except mobile

2. Rely on native

3. The potential is big

4. Need plug-ins

5. Multiple platforms for one set of code

6. Google Dad