In Flutter, what are platform views such as AndroidView and UiKitView for, and why avoid them when a Flutter widget could do the job?
answer
- a native view inside the widget tree
- viewType matches a registered factory
- creationParams need a creationParamsCodec
- needs bounded constraints from its parent
- expensive: extra composition every frame
basics
~20 sPlatform views embed a real native view, such as a map or a web view, inside the Flutter widget tree. They cost extra composition work every frame and add platform-specific limits, so a pure Flutter widget is preferred whenever one exists.
solid answer
~40 s`AndroidView` (Android) and `UiKitView` (iOS) host a native `View` or `UIView` inside the widget tree, so you can reuse something Flutter cannot draw itself — a native map SDK, a web view, a vendor's video player. The widget's `viewType` string must match a factory registered on the host side (`PlatformViewFactory` on Android, `FlutterPlatformViewFactory` on iOS), usually by a plugin; `creationParams` are sent to that factory and need a `creationParamsCodec`. The view fills all available space, so its parent must give bounded constraints, and the native view lives as long as the widget's `State`. The framework's own docs call embedding Android views expensive and say to avoid it when a Flutter equivalent is possible: composing native and Flutter content costs frame time, and each platform brings its own composition and gesture limits.
go deeper
Recall that AndroidView and UiKitView embed native views, need a registered viewType, and are a last resort because they are expensive.
Explain the host-side factory registration, creationParams with a matching codec, the bounded-constraints rule and the State-bound lifetime.
Justify when a native component is worth its per-frame composition cost and platform-specific limits, and plan how to restore native state after recreation.
Decide per feature whether to accept a native dependency or invest in a Flutter-drawn replacement, weighing frame budgets against platform fidelity.
## What a platform view is Flutter normally draws every pixel itself. A **platform view** is the exception: it places a real native view — an Android `View` or an iOS `UIView` — inside the widget tree, and the engine composes it together with Flutter's own output. Transforms, clips and opacity applied from Dart still reach the native view. Typical reasons to use one: - a native map SDK that has no Flutter renderer; - a web view (the `webview_flutter` plugin is built on platform views); - a vendor's native video, payment or camera UI you must show as-is. ## The widgets | Widget | Platform | Hosts | |---|---|---| | `AndroidView` | Android | an Android `View` created by a `PlatformViewFactory` | | `UiKitView` | iOS | a `UIView` created by a `FlutterPlatformViewFactory` | | `AppKitView` | macOS | an `NSView` | | `PlatformViewLink` + `AndroidViewSurface` | Android | the same, with an explicit choice of composition mode | Every one of them takes a **`viewType`** string. On the host side, an app's activity or, more often, a plugin registers a factory under that exact string; if no factory is registered, creation fails. ```dart Widget build(BuildContext context) { const viewType = 'com.example.property/map'; final creationParams = <String, Object?>{'lat': 52.37, 'lng': 4.89}; return switch (defaultTargetPlatform) { TargetPlatform.android => AndroidView( viewType: viewType, creationParams: creationParams, creationParamsCodec: const StandardMessageCodec(), ), TargetPlatform.iOS => UiKitView( viewType: viewType, creationParams: creationParams, creationParamsCodec: const StandardMessageCodec(), ), _ => const Text('Map not supported on this platform'), }; } ``` ## Rules the widget imposes 1. **Bounded constraints.** The widget fills all available space, so its parent must bound it — inside a `ListView` or `Column`, wrap it in a `SizedBox` with a height. 2. **Codec with params.** If `creationParams` is non-null, `creationParamsCodec` must be set, and it should match the codec the native factory was constructed with. 3. **Lifetime follows `State`.** The native view is created with the widget's `State` and released when that `State` is disposed — including when the widget moves in the tree without a key that preserves it. 4. **Hit testing.** `hitTestBehavior` defaults to `PlatformViewHitTestBehavior.opaque`, so the view absorbs hits in its bounds. 5. **Android minimum.** `AndroidView` requires Android API level 23 or later. ## Why avoid them when you can - **Frame cost.** The engine must combine native and Flutter output every frame. Depending on the mode, that means copying the native view into a texture or splitting Flutter's output into layers around it; either way it costs more than drawing a widget. - **Per-platform behaviour.** Android has several composition modes with different trade-offs; iOS has composition limits (for example `ShaderMask` and `ColorFiltered` do not apply to the native view). - **Gestures.** Touches must be negotiated between Flutter recognizers and the native view. - **Two code bases.** Each platform needs native code and its own maintenance. So the interview answer is: use a platform view when you need a native component Flutter cannot reproduce — a real map SDK or browser engine — and use a Flutter widget for anything Flutter can draw. ## Common mistakes - Treating a platform view like a normal widget in an unbounded parent and getting a layout error. - Forgetting that scrolling it off-screen in a lazy list disposes the `State` and recreates the native view later. - Assuming the same widget works on every platform; the `viewType` must be registered per platform.
- Why does an AndroidView inside a Column throw a layout error?The widget sizes itself to fill all available space and requires bounded constraints. A `Column` gives its children unbounded height, so there is no finite size to fill; wrapping it in a `SizedBox` or `Expanded` supplies a bound.
- What happens to the native view when its widget's State is disposed?The platform view is released with it: some resources immediately, some by the platform's garbage collector. Next time the widget is built, a fresh native view is created, so any native state such as a scrolled web page or map camera is lost unless you restore it.
A platform view is like a window cut into a painted theatre backdrop: the painters (Flutter) still paint everything around it, but through the window the audience sees a real street, and keeping the painted scene and the real street lined up costs stagehand effort on every scene change.
saying these in an interview costs you the question
- Platform views are how Flutter renders all its normal widgets.
- A platform view costs no more than any other widget.
- The viewType can be any string; no host-side registration is needed.
- creationParams can be passed without a creationParamsCodec.
- A platform view sizes itself to its native content like Text does.