Flutter Learning Guide 6. file storage and networking 5. interaction, gestures and animation 4.UI layout and controls 3. Familiar with Dart language 2. Write the first application 1. Build development environment

This is the seventh article in a series of study guides.

In this article, we will learn how to use the Flutter plugin together, then learn how to develop the Flutter plugin by developing a Toast plugin, and finally publish it to Pub.

Use of plug-ins

The library of Flutter is managed as a package. Package is divided into two types, Dart Package (also called Library Package) and Plugin Package. When we say Fluter package, we also mean Dart package, which can only use Dart and Flutter apis. When we say the Flutter plugin, we mean the plugin package. The Flutter plugin usually contains platform-specific code. To the user of the package, there is no difference.

Add the dependent

To use a library, we first declare a dependency in pubspec.yaml:

dependencies:

Shared_preferences: ^ 0.4.2

Copy the code

^0.4.2 indicates a version compatible with 0.4.2. We can also specify a specific version of the dependent library:

  • Any: Any version
  • 1.2.3: Specific version
  • <1.2.3: version less than 1.2.3, in addition to <=, >, >=
  • ‘>=1.2.3 <2.0.0’ : specifies a range

Next, perform the flutter Packages GET in the root directory of the project. If you are developing using Android Studio, you can also click the Packages Get button directly on the pubspec.yaml edit page.

The above example is the library published on pub.dartlang.org. In addition, we can also use other sources:

dependencies:

  transmogrify:

    hosted:

      name: transmogrify

      url: http://your-package-server.com

Version: ^ 1.4.0



  kittens:

    git:

      url: git://github.com/munificent/cats.git

Ref: some-branch # Optional



  kittens:

    git:

      url: git://github.com/munificent/cats.git

Path: path/to/kittens # Specifies a path



You can even specify a local path

    transmogrify:

      path: /Users/me/transmogrify

Copy the code

If you have read the PubSpec of Flutter, you will have noticed that Flutter declares:

dependencies:

  flutter:

    sdk: flutter

Copy the code

The SDK is used to import packages shipped with Flutter, currently only Flutter.

use

After importing the relevant package, we can use its API:

import 'package:shared_preferences/shared_preferences.dart';



void foo() async {

  var prefs = await SharedPreferences.getInstance();

  var used = prefs.getBool('used');

  if(! used) {

    prefs.setBool('used'.true);

  }

}

Copy the code

The problem with this type of import is that it imports all the symbols in the library into the global namespace (for example, in the example above, we can use SharedPreferences directly). Sometimes to prevent namespace contamination, we can use AS to give the imported library a name (of course, it is not necessary to use the qualified name for SharedPreferences) :

void foo() async {

  var prefs = await sp.SharedPreferences.getInstance();

  var used = prefs.getBool('used');

  if(! used) {

    prefs.setBool('used'.true);

  }

}

Copy the code

Now that we know how to use the Flutter package, let’s develop our own Flutter plugin.

Developing a plug-in

While learning about Flutter, I wonder if you have noticed that Flutter does not provide a Toast API. To remedy this, in this section we will develop a plug-in that supports Toast.

Before we start development, let’s take a look at how Flutter communicates with platform-specific code.

MethodChannel

Flutter can communicate with platform-specific code via the MethodChannel. The client uses MethodChannel to send method calls and parameters to the server, which also receives the relevant data through MethodChannel.

PlatformChannels

Note that the arrows in the figure above are two-way. That is, we can not only call Android/iOS code from Flutter, but also from Android/iOS. The related parameters are as follows:

Dart Android iOS
null null nil (NSNull when nested)
bool java.lang.Boolean NSNumber numberWithBool:
int java.lang.Integer NSNumber numberWithInt:
int, if 32 bits not enough java.lang.Long NSNumber numberWithLong:
double java.lang.Double NSNumber numberWithDouble:
String java.lang.String NSString
Uint8List byte[] FlutterStandardTypedData typedDataWithBytes:
Int32List int[] FlutterStandardTypedData typedDataWithInt32:
Int64List long[] FlutterStandardTypedData typedDataWithInt64:
Float64List double[] FlutterStandardTypedData typedDataWithFloat64:
List java.util.ArrayList NSArray
Map java.util.HashMap NSDictionary

Create a project

This assumes that the reader is developing using Android Studio.

  1. On the menu, choose File -> New -> New Flutter Project
  2. Select the Flutter Plugin from the panel that pops up and click Next
  3. For Project name, we fill in Flutter_toast2018, and for other information, readers fill in according to their own needs

It is called flutter_toast2018 because there is already a Flutter_toast on the Pub, so 2018 is added to prevent name conflicts.

The generated project has four main directories:

  • Android: Android implementation of plug-in native code
  • Ios: implementation of ios
  • Lib: Dart code. The plug-in’s customers will use the interface implemented here
  • Example: An example of a plug-in

Plug-in development

Android end code implementation

In fact, when we generated the project in the last step, there was already a demo of Flutter that implemented platformVersion. Readers who are interested in Flutter can take a look. Next, let’s develop our own Toast plug-in (note that our implementation only supports Android).

First let’s look at the interface MethodCallHandler:

public interface MethodCallHandler {

  void onMethodCall(MethodCall call, Result result);

}

Copy the code

This interface is used to process local method calls to Flutter. That is, we need to implement the interface that pops up a toast when a Flutter calls us.

This interface is implemented by the FlutterToast2018Plugin (located in the Android directory) :

public class FlutterToast2018Plugin implements MethodCallHandler {

  public static void registerWith(Registrar registrar) {

    // "example.com/flutter_toast2018" is the name of our method channel, which is also needed in the Dart code.

    // To prevent naming conflicts, you can prefix it with the domain name

    final channel = new MethodChannel(registrar.messenger(), "example.com/flutter_toast2018");

    channel.setMethodCallHandler(new FlutterToast2018Plugin());

  }



  @Override

  public void onMethodCall(MethodCall call, Result result) {

    // TODO

  }

}

Copy the code

To pop Toast, we add a Context parameter to the constructor of the FlutterToast2018Plugin:

public class FlutterToast2018Plugin implements MethodCallHandler {

  private final Context mContext;



  public FlutterToast2018Plugin(Context context) {

    mContext = context;

  }



  / / register MethodCallHandler

  public static void registerWith(Registrar registrar) {

    final channel = new MethodChannel(registrar.messenger(), "example.com/flutter_toast2018");

    // The context is via Registrar

    channel.setMethodCallHandler(new FlutterToast2018Plugin(registrar.context());

  }



  // ...

}

Copy the code

Now, implement the onMethodCall method:

public class FlutterToast2018Plugin implements MethodCallHandler {

  // ...



  @Override

  public void onMethodCall(MethodCall call, Result result) {

    // Call. Method is the name of the method

    if (call.method.equals("toast")) {

      // Only one argument can be passed when calling native code. To pass multiple parameters, you can put them in a map.

      The call.arguemnt() method supports Map and JSONObject

      String content = call.argument("content");

      String duration = call.argument("duration");

      Toast.makeText(mContext, content,

                     "short".equals(duration) ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG)

              .show();

      // The command is successfully executed

      result.success(true);

    } else {

      result.notImplemented();

    }

  }

}

Copy the code

The Flutter end

All the Flutter side needs to do is generate a MethodChannel and call the toast method with this MethodChannel:

import 'dart:async';

import 'package:flutter/services.dart';



enum ToastDuration {

  short, long

}



class FlutterToast {

  // The name must correspond to the Java side

  static const MethodChannel _channel =

      const MethodChannel('example.com/flutter_toast2018');



  static Future<bool> toast(String msg, ToastDuration duration) async {

    var argument = {

      'content': msg,

      'duration': duration.toString()

    };

    // The local method is an asynchronous call. 'toast' corresponds to the onMethodCall in our previous Java code

    // The name of the method handled inside the method

    var success = await _channel.invokeMethod('toast', argument);

    return success;

  }

}

Copy the code

The use of plug-in

In this section we modify the example in the example directory of the project to demonstrate the use of the plug-in:

import 'package:flutter/material.dart';



// Import our package first

import 'package:flutter_toast2018/flutter_toast2018.dart';



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



class MyApp extends StatelessWidget {



  @override

  Widget build(BuildContext context) {

    return new MaterialApp(

      home: new Scaffold(

        appBar: new AppBar(

          title: const Text('Plugin example app'),

        ),

        body: new Center(

          child: RaisedButton(

            child: Text('toast'),

            // Plugins are used in the same way as other libraries

            onPressed: () => FlutterToast2018.toast(

              'Toast from Flutter', ToastDuration.short

            ),

          ),

        ),

      ),

    );

  }

}

Copy the code

Release the plugin

As mentioned earlier, PubSpec supports importing dependencies through local paths and Git, but for better management of version dependencies, it is recommended to publish plug-ins to pub.dartlang.org/. In this section, we publish the Toast plug-in we developed earlier to the Pub.

It should be noted that for some well-known reason, Pub.dartlang.org requires a ladder to get up. Although we can also publish flutter- IO. Cn, uploading requires a Google account and a ladder.

Check the configuration

The first is pubspec.yaml. For the Flutter plugin, PubSpec also contains some meta information that readers can fill in as needed, in addition to the plugin dependencies:

name: flutter_toast2018

description: A new Flutter plugin for Android Toast.

Version: 0.0.1

author: Jekton <[email protected]>

homepage: https://jekton.github.io/

Copy the code

In addition, packages published to Pub need to include a LICENSE file, and the easiest way to do this is to select one when creating a repository on GitHub.

Check the plugin

Now, let’s check for any problems with the plug-in by executing the following command at the root of the project:

flutter packages pub publish --dry-run

Copy the code

If all is well, it will print:

.



Package has 0 warnings.

Copy the code

Release the plugin

Publishing the plug-in is the same as the previous step, but without the dry-run argument:

flutter packages pub publish

Copy the code

If this is your first Posting, you will be prompted to verify your Google account. Successful matches package is displayed after the file is uploaded.

Looks great! Are you ready to upload your package (y/n)? y

Pub needs your authorization to upload packages on your behalf.

In a web browser, go to https://accounts
.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&response_type=code&client_id=xxxxxxxxxxxxxx-8grd2eg9tj9f38os6f1urbcvsq399u8n.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A52589&scope=https%3A%2F %2Fwww.googleapis.com%2Fauth%2Fuserinfo.email

Then click "Allow access".



Waiting for your authorization...

Successfully authorized.

Uploading...

Successful uploaded package.

Copy the code

We published in front of the package can be pub.dartlang.org/packages/fl… Or pub. Flutter – IO. Cn/packages/fl… To find it.

The relevant code is posted on GitHub:

git clone https://github.com/Jekton/flutter_toast2018.git

Copy the code

Finally, the Flutter package that we didn’t talk about. To develop a Flutter package, we can select the Flutter Package when creating a project. The only difference between this and the Flutter plugin is that the Flutter package cannot contain platform-specific code (only Dart and the Flutter API can be used). Otherwise, development, distribution, and use of Flutter are no different from the Flutter plugin.


Programming · Thinking · workplace


Welcome to scan code attention