preface

Since the Current stage of Flutter technology stack is not very mature, we often need to use the power of Native platform to supplement this aspect of Flutter when using Flutter for mobile development. In the previous two chapters we learned about the two ways that Flutter can interact with the native platform by learning how to package the Flutter project as an AAR and integrate it into the original biography. However, there are some scenarios where we want our code for Flutter to interact with the native platform to be developed at once and used in multiple places. Just like library files, they can be used by other projects or developers. This is the topic of this article about Flutter plugin development and how the plugin can be incorporated into a project

Course objectives

  • Learn how to create a Flutter plugin and understand the plugin project structure
  • How to introduce plug-ins into existing projects

1. Create a Flutter plugin project

Creating a Flutter project is the same as creating a Flutter project, except that the project type is slightly different when creating a Flutter project.

1.1 New Project

1.2 Select the Flutter Plugin

Then create a new Flutter Applicition by giving the project a name, selecting the project path, and other initial configurations until next until the plugin project is initialized. After the operation of the reader will see, there is no need to pay special attention to the place, I will not one by one texture.

1.3 Plug-in project structure

From the following diagram, we can see that the Structure of the Flutter project is almost the same as that of the normal Flutter project, except that there is an example directory. When you open the example directory, you will find that there is a whole Flutter project under this directory. Yes, this example is for the convenience of us in the development of plug-in to debug whether the function of development can be used normally, if no problem can be released or to other projects for normal use.

Knowledge is through the use of the plug-in development actually used in our last lesson about Flutter with Native platform to complete the interaction way, let the Flutter using Native functionality to complete an operation, pluggable just put the code to the platform operation modular, late to other projects or others introduction, make a development code, We will not go into detail about the functional code implementation logic of the plugin because of the knowledge we covered in the last article. Here we will briefly analyze the project of Flutter plugin used in this course.

First look at the renderings:

In the plug-in project above, we implemented the function of obtaining the system version number and a simple calculator. Let’s take a look at the configuration in the plug-in project.

Business implementation logic on android side of plug-in project:

class FlutterCalcPlugin : MethodCallHandler { companion object { @JvmStatic fun registerWith(registrar: Registrar) { val channel = MethodChannel(registrar.messenger(), "flutter_calc_plugin") channel.setMethodCallHandler(FlutterCalcPlugin()) } } override fun onMethodCall(call: MethodCall, result: Result) { if (call.method == "getPlatformVersion") { result.success("Android ${android.os.Build.VERSION.RELEASE}") } else if (call.method == "getResult") { var a = call.argument<Int>("a") var b = call.argument<Int>("b") result.success((a!! + b!!) .toString()) } else { result.notImplemented() } } }Copy the code

Since the plugin is developed to be used on the FLUTTER side, in other words referenced to the DART file, the following method declarations defined in the DART file are the methods our plugin provides to callers. GetResult (int A, int b) : computes the sum of two numbers

The two methods interact with the platform through the methodChannel, use the native side to complete some specific logic, and then return the result of execution to the caller. Once the plug-in definition is complete and successfully imported into our project, we can import the relevant classes and method references into our project and use our own components as normal.

Plugin project flutter side code:


class FlutterCalcPlugin {
  static const MethodChannel _channel =
      const MethodChannel('flutter_calc_plugin');

  static Future<String> getplatformVersion async {
    final String version = await _channel.invokeMethod('getPlatformVersion');
    return version;
  }

  /** * computes the sum of two numbers */
  static Future<String>  getResult(int a, int b) async {
    Map<String, dynamic> map = {"a": a, "b": b};
    String result = await _channel.invokeMethod("getResult", map);
    print(result+"----------aa--");
    returnresult; }}Copy the code

I did not elaborate on the part of interaction with the platform here, because we have already covered relevant knowledge points in the last article. If readers do not quite understand the logic of interaction with the platform, Suggest going to read an article on the first introduction to Flutter advanced trip (19) Flutter and native platform interaction the plug-in code complete address: https://github.com/xiedong11/flutter_calc_plugin.git

2. Plug-ins are introduced into existing projects

To import our developed plug-in project into an existing project, we can import it via the Github repository or locally. Of course, we can also upload our developed plug-in project to the Dart Packages of Flutter and import it using the pubspec.ymal file with the version number. Uploading the configuration of Dart Packages is a bit of a hassle. Due to space limitations, I will only introduce the first two methods here. If you are interested in uploading The Configuration of Dart Packages, you can contact me privately or I will write a separate blog post to explain it in detail.

2.1 Local Import

As shown in the figure, I put the plug-in project in the plugin file under the project and directory. We can define the name of the plug-in project by ourselves. Here I define it as Flutter_calc_plugin. Add the path of the plug-in imported after the normal use of plug-in functions.

Flutter_calc_plugin: path: plugin/flutter_calc_pluginCopy the code
2.2 Import using the Github Repository Address

The github repository is relatively easy to import. You don’t need to copy the github repository to your site. You just need to configure the address of the plugin in the yamL file of your project to import the plugin.

# out on introducing plug-in depends on flutter_calc_plugin: git: url: https://github.com/xiedong11/flutter_calc_plugin.gitCopy the code

As a minor detail, yamL files are so strict about indentation that readers should be careful about indentation when configuring plug-in references or other third-party libraries.

There is no fixed answer as to which way to use the above two plug-ins. It depends entirely on your personal preference and the needs of the plug-in. For example, if your plug-in is developed and hardly needs modification, I suggest referencing it through Github or uploading to Dart Packages. This not only let you update or clear and project management of engineering structures, but if the first stage of the development of your plug-in is not mature, or need to change a lot, it is recommended to use the local way of import, so the modified debugging code is convenient, but also saves frequently upload plug-in version to dart packages or making up.

There are also scenarios where the plugin is not developed by yourself, but is developed by someone else on Github or Dart Packages, but the plugin doesn’t fully meet your business needs, or you need to re-customize the UI or add logic based on the plugin. At this time, you can also download the plug-in developed by others to the local, and then introduce it into your project by local way and modify it for your business until it is modified to your satisfaction, and then import it into the project by local way.

At the end of the article, post a code implementation of the GIF example above for your reference:

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

import 'package:flutter/services.dart';
import 'package:flutter_calc_plugin/flutter_calc_plugin.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState(a) => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';
  String addResult = ' ';
  TextEditingController _addNumber1Controller,_addNumber2Controller;

  @override
  void initState(a) {
    super.initState();
    _addNumber1Controller = TextEditingController();
    _addNumber2Controller = TextEditingController();
  }

  Future<void> getAddResult(a) async {
    int addNumber1= int.parse(_addNumber1Controller.value.text);
    int addNumber2=int.parse(_addNumber2Controller.value.text);

    String result = ' ';
    try {
      result = await FlutterCalcPlugin.getResult(addNumber2, addNumber1);
    } on PlatformException {
      result = 'Unknown error';
    }
    setState(() {
      addResult = result;
    });
  }

  Future<void> initPlatformState(a) async {
    String platformVersion;

    try {
      platformVersion = await FlutterCalcPlugin.platformVersion;
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }

    if(! mounted)return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plug-in Sample'),
        ),
        body: Center(
            child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            MaterialButton(
              color: Colors.amber,
              child: Text("Get system version"),
              onPressed: (a) {
                initPlatformState();
              },
            ),
            Text('Current version: $_platformVersion\n'),
            SizedBox(height: 30),
            Text("Adding calculator"),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,

              children: <Widget>[
                SizedBox(
                  width: 80,
                  child: TextField(
                    controller: _addNumber1Controller,
                    keyboardType: TextInputType.number,
                  ),
                ),
                Text("+",style: TextStyle(fontSize: 26),),
                SizedBox(
                  width: 80,
                  child: TextField(
                    controller: _addNumber2Controller,
                    keyboardType: TextInputType.number,
                  ),
                ),
                Text("=",style: TextStyle(fontSize: 26),),
              ],
            ),
            SizedBox(height: 30),
            MaterialButton(
              color: Colors.amber,
              child: Text(The result is equal to), onPressed: () { getAddResult(); }, ), Text(addResult), ], )), ), ); }}Copy the code

Finally this chapter as well as all the complete code for the following column, readers if still don’t quite understand, can download the code to run a project, slowly to formulate specific implementation details: under column code warehouse: https://github.com/xiedong11/flutter_app.git