Skip to main content

Using Platform Views

1. Understanding Platform Views Concept

Note: Platform Views in Flutter allow you to embed native platform views (such as Android Views or iOS UIViews) within a Flutter app, enabling access to native functionality while maintaining the Flutter UI.
Feature Description Usage
AndroidView Embeds an Android View in a Flutter app. AndroidView(viewType: 'com.example.myview');
UiKitView Embeds a UIKit view in a Flutter app (iOS). UiKitView(viewType: 'com.example.myuiview');
Platform Views Enables interaction between Flutter and native platform views. Used for performance-critical or platform-specific UI components.

Example: Using AndroidView

import 'package:flutter/material.dart';

class MyAndroidView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Platform Views Example")),
        body: Center(
          child: AndroidView(
            viewType: 'com.example.myview',
          ),
        ),
      ),
    );
  }
}

Example: Using UiKitView

import 'package:flutter/material.dart';

class MyUiKitView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Platform Views Example")),
        body: Center(
          child: UiKitView(
            viewType: 'com.example.myuiview',
          ),
        ),
      ),
    );
  }
}

Key Points

  • Platform Views provide a bridge between Flutter and native platform views.
  • They are useful for integrating existing native UI components or performance-critical features.
  • Platform Views require platform-specific setup in Android and iOS projects.

2. Embedding Android Views

Flutter allows embedding native Android views within a Flutter app using platform views. This is useful for integrating existing Android UI components or accessing native Android APIs.

Property Description Values
platformViewCreationPolicy Controls when the platform view is created. PlatformViewCreationPolicy.offline, PlatformViewCreationPolicy.online
viewType Unique identifier for the platform view. String
layoutDirection Layout direction of the view. LayoutDirection.ltr, LayoutDirection.rtl

Example: Embedding Android View

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Android View Example")),
        body: PlatformViewLink(
          viewType: "com.example.androidview",
          surfaceFactory: (context, controller) {
            return AndroidViewSurface(
              controller: controller,
              gestureRecognizers: const {},
              layoutDirection: LayoutDirection.ltr,
            );
          },
        ),
      ),
    );
  }
}
Note: Ensure that the viewType matches the one registered in your Android code.
Warning: Platform views can impact performance and should be used sparingly.

3. Embedding iOS Views

Flutter allows embedding native iOS views using platform views. This is useful for integrating existing iOS components or leveraging platform-specific features.

Property Description Values
platformViewCreationPolicy Controls how the platform view is created. PlatformViewCreationPolicy.offline, PlatformViewCreationPolicy.online
viewType Identifier for the native view type. NSString
layoutDirection Layout direction for the view. LayoutDirection.ltr, LayoutDirection.rtl

Example: Embedding an iOS View

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

class iOSViewEmbedder extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return PlatformViewLink(
      viewType: 'io.flutter.embedding.android.FlutterImageView',
      surfaceFactory: (context, controller) {
        return AndroidViewSurface(
          controller: controller,
          gestureRecognizers: const {},
        );
      },
      platformViewCreationPolicy: PlatformViewCreationPolicy.offline,
    );
  }
}
Note: Ensure that the viewType matches the native view identifier registered in your iOS project.
Warning: Platform views may impact performance and should be used sparingly.

The PlatformViewLink widget in Flutter allows you to create a link between a platform view and a Flutter widget, enabling interaction between native platform views and Flutter's UI.

Property Description Values
viewType Specifies the type of platform view to create. 'native-view' or custom string
link Provides a link to the platform view. PlatformViewLink instance
platformViewCreationParams Parameters used to create the platform view. PlatformViewCreationParams
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class PlatformViewExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Platform View Example')),
      body: Center(
        child: PlatformViewLink(
          viewType: 'native-view',
          onCreatePlatformView: (params) {
            return PlatformViewsService.initNativeView(
              id: params.id,
              viewType: 'native-view',
              layoutDirection: TextDirection.ltr,
            );
          },
        ),
      ),
    );
  }
}

5. Using HtmlElementView for Web

Example: Embedding HTML in Flutter Web

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('HtmlElementView Example')),
        body: HtmlElementView(viewType: 'my-html-view'),
      ),
    );
  }
}
Property Description Values
viewType Identifier for the HTML element view 'my-html-view'
onPlatformViewCreated Callback when the view is created Function(int id)
Note: HtmlElementView is only supported on web and requires the view to be registered with registerViewFactory.
Warning: Ensure that the HTML element is properly registered before using it in HtmlElementView.

6. Implementing Native View Controllers

Example: Implementing a Native View Controller in iOS

import UIKit
import Flutter

@objc public class NativeViewController: UIViewController {
  private var flutterView: UIView?

  override public func viewDidLoad() {
    super.viewDidLoad()
    setupFlutterView()
  }

  private func setupFlutterView() {
    let flutterEngine = FlutterEngine(name: "my_engine")
    flutterEngine.run()
    let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
    flutterView = flutterViewController.view
    flutterView?.frame = view.bounds
    view.addSubview(flutterView!)
  }
}
Property Description Notes
platformView Instance of the native view controller Used to embed native UI components
engine Flutter engine instance Must be initialized before embedding
Note: Ensure the Flutter engine is properly initialized before attempting to embed native views.
Warning: Native view controllers must be managed carefully to avoid memory leaks or UI conflicts.

7. Handling View Lifecycle

Example: Platform View Lifecycle Management

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

class PlatformViewLifecycle extends StatefulWidget {
  @override
  _PlatformViewLifecycleState createState() => _PlatformViewLifecycleState();
}

class _PlatformViewLifecycleState extends State<PlatformViewLifecycle> {
  static const String platformViewType = 'platform_view';
  late PlatformViewController controller;

  @override
  void initState() {
    super.initState();
    controller = PlatformViewsService.initPlatformView(
      id: 'platform_view_id',
      viewType: platformViewType,
      layoutDirection: TextDirection.ltr,
    );
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return PlatformViewLink(
      url: 'https://example.com',
      platformViewCreationParams: const PlatformViewCreationParams(),
      builder: (BuildContext context, PlatformViewController controller) {
        return Container(
          width: 300,
          height: 200,
          child: AndroidView(
            controller: controller,
            gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{
              Factory<OneSequenceGestureRecognizer>(() => EagerGestureRecognizer()),
            },
          ),
        );
      },
    );
  }
}
Method Description Notes
initPlatformView Initializes a platform view with given parameters. Must be called before using the view. Returns a PlatformViewController.
dispose Releases resources associated with the view. Should be called in dispose to prevent memory leaks.
setViewSize Updates the size of the platform view. Useful for dynamic resizing during runtime.
Note: Platform views are managed by the Flutter engine and must be explicitly disposed to avoid memory leaks.

8. Managing Performance with Platform Views

Performance Considerations

  • Platform views can cause jank if not managed carefully
  • Use AndroidView and UiKitView judiciously
  • Minimize the number of platform views in a single screen
Aspect Impact Best Practice
Rendering Platform views are rendered outside the Flutter rendering tree Use HardwareLayer for better performance
Memory Usage Each platform view consumes additional memory Reuse views where possible
Frame Rate Can drop frame rate if too many views are active Limit concurrent platform views to 2-3

Example: Using HardwareLayer

import 'package:flutter/material.dart';

class PerformanceExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: AndroidView(
          androidFlingGestureEnabled: true,
          hardwareAccelerated: true,
          onPlatformViewCreated: (int id) {
            // Handle view creation
          },
        ),
      ),
    );
  }
}
Note: Enabling hardware acceleration can significantly improve rendering performance for complex platform views.
Warning: Avoid nesting multiple platform views inside each other as it can lead to severe performance degradation.

Optimization Workflow

  1. Profile the app using Flutter DevTools
  2. Identify platform view usage patterns
  3. Implement hardwareAccelerated property
  4. Limit concurrent platform views
  5. Monitor frame rate post-optimization

9. Using webview_flutter Package

Example: Basic WebView Usage

import &#x27;package:flutter/material.dart&#x27;;
import &#x27;package:webview_flutter/webview_flutter.dart&#x27;;

class WebViewExample extends StatefulWidget {
  @override
  _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  late WebViewController controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("WebView Example")),
      body: WebView(
        initialUrl: &#x27;https://flutter.dev&#x27;,
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );
  }
}
Property Description Values
initialUrl URL to load initially String
onWebViewCreated Callback when WebView is created Function(WebViewController)
javascriptMode Enables JavaScript in WebView JavaScriptMode.off, JavaScriptMode.unsafe
Note: Ensure you add the required permissions in your app's manifest for Android and Info.plist for iOS.

10. Using google_maps_flutter Package

Example: Displaying a Google Map

import &#x27;package:flutter/material.dart&#x27;;
import &#x27;package:google_maps_flutter/google_maps_flutter.dart&#x27;;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MapScreen(),
    );
  }
}

class MapScreen extends StatefulWidget {
  @override
  _MapScreenState createState() => _MapScreenState();
}

class _MapScreenState extends State<MapScreen> {
  late GoogleMapController mapController;

  final CameraPosition _cameraPosition = CameraPosition(
    target: LatLng(37.42796133580664, -122.0857496559622),
    zoom: 14.0,
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Google Map")),
      body: GoogleMap(
        initialCameraPosition: _cameraPosition,
        onMapCreated: (GoogleMapController controller) {
          mapController = controller;
        },
      ),
    );
  }
}
Property Description Values
initialCameraPosition Initial position of the map camera CameraPosition
onMapCreated Callback when the map is created void Function(GoogleMapController)
mapType Style of the map MapType.normal, MapType.satellite, MapType.terrain, MapType.hybrid
zoomControlsEnabled Whether zoom controls are shown true, false
Note: Ensure you have added the necessary API keys in your app's configuration files for Android and iOS.

Was this article helpful?