Flutter PlatformView: How to host native android and iOS view in Flutter

CodingWithTashi
Flutter Community
Published in
8 min readSep 11, 2022

--

Flutter does a great job when it comes to building beautiful UI by leveraging all these widgets that are available in flutter SDK, But sometime we might want to show the same native UI in your flutter application.

This is where Flutter Platform View comes to the rescue.

Photo by AltumCode on Unsplash

Hello guys, This is CodingWithTashi and in this shitty post, we are going to learn how to host native Android and iOS views in your Flutter app with Platform Views.

This post is inspired from How to create Widgets from Native Views by Felix (Author or flutter_bloc). Feel free to check out his article as well.

Flutter offer PlatformView which allows us to embed Android or iOS Views in the flutter widget hierarchy without doing much work.

As Felix mentioned in his post This opens the door to many possibilities like fully integrated maps and web views in your flutter applications.

At the time of writing this post, Flutter support only mobile platform

  • Android
  • iOS

Desktop support is not available yet, You can refer to this open issue for more updates.

Also, Flutter provides very good documentation on Hosting Platform View for android and iOS, Feel free to check out their official documentation link attached below.

Before we start here are some quick things to note are:

  • As of now, supported platforms are Android and iOS only

Android:

  • They are two ways to host PatformView on android
  1. Virtual displays

Virtual displays render the android.view.View instance to a texture, so it’s not embedded within the Android Activity’s view hierarchy. Certain platform interactions such as keyboard handling and accessibility features might not work.

  • minSdkVersion should be 20 for Virtual display

2. Hybrid composition

Hybrid composition appends the native android.view.View to the view hierarchy. Therefore, keyboard handling and accessibility work out of the box. Prior to Android 10, this mode might significantly reduce the frame throughput (FPS) of the Flutter UI. See performance for more info

  • minSdkVersion should be 19 if you are using Hybrid composition.

iOS:

  • There is only one way to host PatformView on iOS

iOS only uses Hybrid composition, which means that the native UIView is appended to the view hierarchy.

Alright with that said In this post we are going learn how to host platform view in android and iOS by creating a simple WebViewPluginwhere we will expose a native android and iOS WebView as a Flutter Widget.

These are the topic that we will cover.

  • How to communicate dart to native?
  • How to create a WebView plugin from scratch?
  • How to host a native WebView in the flutter widget?

Here is an overview of how our map_plugin works.

Overview of web_view plugin

Great, now that we know what and how we are hosting our Platforms let’s try to understand by building a simple WebViewPlugin.

Let’s get our hands dirty 😊.

The first thing we’re going to need to do is to create a new flutter plugin:

Create a new flutter project in android studio
Enter a project name, Select the project type as a plugin instead of an application
Once the Plugin is created you should see the project structure above.

We will write all android code in an android folder and iOS logic in an ios folder accordingly.

example folder is used to test our plugin and the lib folder is where we write our dart logic to communicate with android and iOS.

After the Flutter Plugin has been created successfully, we can start by creating our WebView class in ./lib/web_view.dart

In this code, we are returning AndroidView andUiKitView base on the platform.

For the full AndroidView and UiKitView documentation check out https://docs.flutter.io/flutter/widgets/AndroidView-class.html.

https://api.flutter.dev/flutter/widgets/UiKitView-class.html

An important thing to note here is that when we create AndroidView or UiKitView on lines no 15 and 20 we need to provide a viewTypewhich we will use at a later point in time.

You might get a red error in the test folder and example folder. Since we are not going to do any test cases for this plugin, You can delete the test folder and fix the example folder by removing the error code within the main.dart file. (We will fix it later)

Additionally, we have provided onPlatformCompleted method so that we can provide the WebView widget with a WebViewController which we can then use to update its URL using setUrlmethod.

Next, we need to work on the Android implementation of our WebViewPlugin.

Android Implementation

To make our life easier let's open android/src/main/kotlin/{organization_name}/WebViewPlugin.kt-> Select Open for Editing in Android Studio.

Then Android project in the new window and sync the gradlefirst. Once done replace your WebViewPlugin.kt content with the following

All we are doing here is adding the extending WebViewPlugin with FlutterPlugin and then override two methods.

In onAttAchedToEngine method, we registerViewFactory by providing the viewType which we defined earlier in webview.dart as well as providing a WebViewFactory which will be creating our native WebView as a PlatformView.

You will get an error for WebViewFactory. Next, we fix this issue by creating WebViewFactory.kt at android/src/main/kotlin/{organization_name}/ and extend PlatformViewFactory.

Our WebViewFactory implements the create the method which returns a PlatformView (in our case it will return a FlutterWebView). Now you can go back to WebViewPlugin.kt and fix the earlier error by importing WebViewFactory.kt

at this point, you will get an error for FlutterWebView since this class doesn't exist. We will fix it by creating FlutterWebView.kt at android/src/main/kotlin/{organization_name}/ and implement PlatformView as well as MethodCallHandler so that we can have our native view painted as a flutter widget and be able to receive data from dart via a MethodChannel.

FlutterWebView creates a new WebView and sets up a MethodChannel so that the WebView can receive data from dart code and make updates (in this case update the URL).

In order to implement PlatformView, we need to override getView and return our webView as well as override dispose (which in this case destroys WebView when PlatformView is destroyed).

In order to implement MethodCallHandler, we need to override onMethodCall and, depending on the method, either call our internal setUrl method (to update the WebView URL) or return result.notImplemented since we currently don’t support any other methods.

Now it’s time to test our new WebView widget!

Open flutter project, Go to ./example/lib/main.dart and replace it with the following code:

This should look familiar. We are running a MaterialApp that renders a Scaffold. We have our Column that contains TextFormField to enter url ,Elevated to load the url in the WebView.

We also have our implementation for onWebViewCreated where we call the setUrl method.

We can also set the url manually with the help of TextEditingController and WebViewController.

With that said our Android Implementation is done, Quite work huh? You have learned a lot as well.

It’s time to run our example flutter app and take a look at what we’ve built.

Great! We’ve proven that you can now create any native Android view as a flutter widget which is pretty powerful and interesting.

You should also be able to run iOS applications though WebView will not work since we have not implemented iOS logic yet.

Let’s see how we can achieve the same thing in iOS as well, don’t worry we have done most of the work already. Let's straight go to the iOS implementation.

iOS Implementation

Open ios/Classes/SwiftWebViewPlugin.swift. You can either continue using Android Studio or open the same project in Xcode. I would encourage you to use Xcode since you can take advantage of IntelliSense.

Important: To open your project in Xcode, head over to example -> ios -> Runner -> Select tool on top option menu -> Flutter -> Open ios Module in Xcode

Screenshot attached below

This will open Xcode IDE
In Xcode, You should able to navigate and see this Classes file under this long path.

You can also run the application one more time in the simulator to see if all work fine.

Okay, now that is done, let's replace SwiftWebViewPlugin.swift it with the following content.

All we are doing here is extending SwiftWebViewPlugin with FlutterPlugin and then added register method.

In registermethod, Similar to android, we register registerViewFactory by providing WebViewFactory which will be creating our native WebView as a PlatformView and the withId which we already defined earlier in webview.dart

You will again get an error for WebViewFactory. Next, we fix this issue by creating WebViewFactory.swift in the same path.

Create swift file WebViewFactory.swift under ios/Classes/ and extend PlatformViewFactory.

Our WebViewFactory implements the create the method which returns a PlatformView (in our case it will return a FlutterWebView).

at this point, you will get an error for FlutterWebView since this class doesn’t exist. We will fix it by creating FlutterWebView.swiftat the same location.

Create swift file FlutterWebView.swift underios/Classes/ and implement FutterPlatformView so that we can have our native view painted as a flutter.

FlutterWebView creates a new WebView and sets up a MethodChannel so that the WebView can receive data from dart code and make updates (in this case update the URL).

In order to implement PlatformView, we need to override view and return our webView .

We have also added onMethodCall and, depending on the method, either call our internal setUrl method (to update the WebView URL) or return result(FlutterMethodNotImplmented) since we currently don’t support any other methods.

With that said our iOS Implementation is also done, Yay!! If you are still reading this, You have done a great job learning how to build your own plugin with platform view.

It’s time to run our crappy example app and take a last look and see what we’ve built.

Seems working fine. We have not cover any test cases for this plugin since this is not a production plugin. so we’ll cover this at some other time. You can check out the complete source code at https://github.com/codingwithtashi/flutter_web_view.

Thanks, guys, That’s all for now, Make sure to give a clap 👏 and leave some engagement. If there is any correction or feedback feel free to leave a comment as well.

If any of my shitty posts help you in any way, you can consider buying me a cup of coffee. I will personally thank you 🙏.

buymeacoffee.com/codingwithtashi

Check out similar posts from CodingWithTashi. Connect me on Twitter or Linkedin

Follow Flutter Community on Twitter: https://www.twitter.com/FlutterComm

--

--