Creating a Flutter Plugin | Dialog Box

Ashish Rawat
Jan 12, 2019 · 6 min read

What is the Flutter plugin?

For the plugin we need to write android and ios specific code, We can either user Kotlin or Java for Android and swift or objective-c for iOS.

Flutter can do anything that a native application can through the use of Platform Channels and Message Passing.

Flutter instructs the native iOS/Android code to perform an action and returns the result to Dart.

Image for post
Image for post
Flutter Directory Structure

In the directory structure of a Flutter app, you’d notice that along with the lib directory which contains Dart code, there is also an android and an ios directory. These contain the iOS and the Android hosts, these native projects that will run the compiled Dart.

Image for post
Image for post

To introduce communication, all we need is to create a Platform Channel, such as MethodChannel, in both the Dart and the host(Android and iOS).

MethodChannel is used to communicate the native code of android and iOS to flutter (dart code).

This is the basic understanding of the flutter plugin now let’s see why plugins are required.

Why Plugin Required?

Creating your own plugin:

These are the following steps to create a plugin:

Open the android studio got to File>> New >> New flutter project.

Image for post
Image for post

Click on the New flutter project >>Select the Flutter plugin option.

Image for post
Image for post

Set name of the plugin :

Image for post
Image for post

In this, I have created a Dialog Box plugin because flutter does not support Dialog box.

Image for post
Image for post
Flutter Directory Structure

By default, this looks like a flutter project we have one Android folder one example folder and one iOS folder and one lib folder

We also have one ore folder that is an example.

In this example folder, we also have another flutter code where we can test our flutter plugin within an app.

Now if you see the file under project_name -> lib, you will find the default code as

import 'dart:async';import 'package:flutter/services.dart';class FlutterAlertDemo {static const MethodChannel _channel =const MethodChannel('flutter_alert_demo');static Future<String> get platformVersion async {final String version = await _channel.invokeMethod('getPlatformVersion');return version;
}
}

So we have a property that platformVersion which is asking _channel to invoke one method which is getting platform version which is defined in Android as well as in iOS and from (‘getPlatformVersion) we are getting the version and we are returning this version to our flutter project.

This version will get from the static get method initPlatformState() in the main.dart file inside the example directory

Above code will be communicated with the native code that you will write in Android and iOS files.

Android Native code(java code):

package adhoc.successive.com.flutteralertdemo;
import android.app.Activity;
import android.app.Dialog;
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;
/** FlutterAlertDemoPlugin */
public class FlutterAlertDemoPlugin implements MethodCallHandler {
/** Plugin registration. */
public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_alert_demo");
channel.setMethodCallHandler(new FlutterAlertDemoPlugin());
}
@Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
}
}

FlutterAlertDemoPlugin class implements the MethodCallHandler so we have to @override onMethodCall method.

( project_name -> ios)

iOS Native code(swift code):

import Flutter
import UIKit
public class SwiftFlutterAlertDemoPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "flutter_alert_demo", binaryMessenger: registrar.messenger())
let instance = SwiftFlutterAlertDemoPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
result("iOS " + UIDevice.current.systemVersion)
}
}

Now we will write platform specific code

Android Native code(project_name -> android -> src):

iOS Native code(project_name -> iOS -> Classes):

The above two code files of android and ios are ready now we need to implement our invoke method in the file under (project_name -> lib).

As we want to invoke the method that will return the output( in our case we will receive all the images).

Now we will make a static method to show dialog box

In the lib folder, we have dialog_box_plugin dart file we will make a static method to show dialog box.

static get showAlertDialog async {
await _channel.invokeMethod('showAlertDialog');
}

Dart file (project_name -> lib):

import 'dart:async';import 'package:flutter/services.dart';class FlutterAlertDemo {
static const MethodChannel _channel =
const MethodChannel('flutter_alert_demo');
static Future<String> get platformVersion async {
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
static get showAleartDialog async {
await _channel.invokeMethod('showAlertDialog');
}
}

Now, your first plugin is ready to use.

So how we will test whether our app plugin is working or not?

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_gallery_plugin/flutter_gallery_plugin.dart';
void main() => runApp(MyApp());class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
@override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
platformVersion = await FlutterGalleryPlugin.platformVersion;
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Text('Running on: $_platformVersion\n'),
),
),
);
}
}

Now you can change this file according to your need

In my case I need to show the dialog box so

FlutterAlertDemo.showAleartDialog();

Example code(project_name -> example -> lib):

Here are some Screenshots of output:

Android:

Image for post
Image for post

iOS:

Image for post
Image for post

How to publish plugin:

flutter packages pub publish--dry-run
flutter packages pub publish

Thanks for reading this article ❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.

Connect with me on LinkedIn.

Check my GitHub repositories.

Follow me on Twitter.

Flutter Community

Articles and Stories from the Flutter Community

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store