Documentation of Flutter plugin development

tool

  • Flutter 1.9.1

  • AndroidStudio 3.5.3

  • XCode 11.2.1

Create a Flutter project named Flutter_plugin_demo, hereinafter referred to as the master project.

Android part of plug-in development

Right-click on the project name and create a Moudle named Flutter_plugin. Select the module that contains the Flutter Plugin. You can rely on either Kotlin or Swift depending on which language the Plugin supports.

Flutter_plugin automatically creates a Flutter project for Example after the Plugin is created. The MyApp class name under the test package under Example conflicts with the main project class name.

Run the example project

Right-click example/lib/main dart, Run the main. The dart. If the build succeeds in the IOS emulator but the package fails as follows:

The application's Info.plist does not contain CFBundleVersion.
Copy the code

Add it to example/pubspec.yaml

version: 1.0. 0+1
Copy the code

Run it again.

This shows that the plug-in itself has already helped us achieve the function of obtaining the running platform. The following is a simple toast function.

Open the Flutter_plugin project with AndroidStudio File/Open:

In addition, you can also select the Android folder, right click on it, and find the Flutter,Open Android Module in Android Studio, as shown below. Because sometimes I write code after opening the Flutter in this way without any API prompts, I try all kinds of attempts. Depends on the individual, the puzzle is right.

Edit FlutterPlugin. Java

package com.hcl.flutter_plugin;

import android.util.Log;
import android.widget.Toast;

import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;

/** FlutterPlugin */
public class FlutterPlugin implements MethodCallHandler {

  private static final String TAG = FlutterPlugin.class.getSimpleName();


  private final Registrar registrar;

  / / structure
  private FlutterPlugin(Registrar registrar) {
    this.registrar = registrar;
  }


  /** * Plugin registration. */
  public static void registerWith(Registrar registrar) {
    final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_plugin");
    channel.setMethodCallHandler(new FlutterPlugin(registrar));
  }


  // Method calls from Flutter
  @Override
  public void onMethodCall(MethodCall call, Result result) {

    String target = call.method;
    switch (target) {
      case "getPlatformVersion":
        result.success("Android " + android.os.Build.VERSION.RELEASE);
        break;
      case "toast":
        String content = (String) call.arguments;
        Log.d(TAG, "toast: " + content);
        showToast(content);
        break;
      default:
        result.notImplemented();
        break; }}/** * displays Toast **@param content
   */
  private void showToast(String content) { Toast.makeText(registrar.context(), content, Toast.LENGTH_SHORT).show(); }}Copy the code

Edit flutter_plugin. Dart

  • flutter_plugin/lib
import 'dart:async';

import 'package:flutter/services.dart';

class FlutterPlugin {

  There are other ways to interact with MethodChannel
  static const MethodChannel _channel =
      const MethodChannel('flutter_plugin');

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

  /** * displays Toast */
  static Future<void> showToast(String content)async {
    await _channel.invokeMethod("toast",content); }}Copy the code

Call running

 FlutterAndroidPlugin.showToast("Hello World");
Copy the code

Only the Android part of the code is implemented here, so it only runs on the Android emulator.

Implementation on IOS

Open the iOS project in the Example project and find Runner. Xcworkspace in the iOS directory. Find the flutterplugin. m file with the following directory structure:

Modify the handleMethodCall method

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
    NSString* methodName=call.method;
    NSString * params = call.arguments;
  if ([@"getPlatformVersion" isEqualToString:methodName]) {
    result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
  } else if([@"toast" isEqualToString:methodName ]){

      [self showMessage:params duration:2];

  }else{ result(FlutterMethodNotImplemented); }}Copy the code

Add method:

//Toast- (void)showMessage:(NSString *)message duration:(NSTimeInterval)time
{
    CGSize screenSize = [[UIScreen mainScreen] bounds].size;

    UIWindow * window = [UIApplication sharedApplication].keyWindow;
    UIView *showview =  [[UIView alloc]init];
    showview.backgroundColor = [UIColor grayColor];
    showview.frame = CGRectMake(1.1.1.1);
    showview.alpha = 1.0 f;
    showview.layer.cornerRadius = 5.0 f;
    showview.layer.masksToBounds = YES;
    [window addSubview:showview];

    UILabel *label = [[UILabel alloc]init];
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
    paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;

    NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:15.f],
                                 NSParagraphStyleAttributeName:paragraphStyle.copy};

    CGSize labelSize = [message boundingRectWithSize:CGSizeMake(207.999)
                                             options:NSStringDrawingUsesLineFragmentOrigin
                                          attributes:attributes context:nil].size;
    label.frame = CGRectMake(10.5, labelSize.width +20, labelSize.height);
    label.text = message;
    label.textColor = [UIColor whiteColor];
    label.textAlignment = 1;
    label.backgroundColor = [UIColor clearColor];
    label.font = [UIFont boldSystemFontOfSize:15];
    [showview addSubview:label];

    showview.frame = CGRectMake((screenSize.width - labelSize.width - 20) /2,
                                screenSize.height - 100,
                                labelSize.width+40,
                                labelSize.height+10);
    [UIView animateWithDuration:time animations:^{
        showview.alpha = 0;
    } completion:^(BOOL finished) {
        [showview removeFromSuperview];
    }];
}
Copy the code

Can. Run tests:

References to the Flutter Plugin

Dart/example/main.dart/example/main.dart/example/main.dart/example/main.dart/example/main.dart

Dev_dependencies: flutter_test: SDK: flutter_plugin: path: flutter_plugin #Copy the code
import 'package:flutter/material.dart';
import 'package:flutter_plugin/flutter_plugin.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); }}class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Main"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            FlutterPlugin.showToast("Say Hello");
          },
          child: Text("Say Hello"),),),); }}Copy the code
rendering

The last

The source address