Slide 1

Slide 1 text

WebViews in Flutter Does it really work? Lara Martín @Lariki Flutter/Dart GDE - Android Developer Flutter onAir GDG Brno, Czechia

Slide 2

Slide 2 text

What is a WebView?

Slide 3

Slide 3 text

Why we need WebViews? Use cases Perform social login Show static content (e.g. FAQ) Payment confirmation Avoid for Making an app that is just a web

Slide 4

Slide 4 text

https://pub.dev/packages/webview_flutter

Slide 5

Slide 5 text

Setup # pubspec.yaml dependencies: flutter: sdk: flutter webview_flutter: ^0.3.22

Slide 6

Slide 6 text

Implementation • Not reimplemented in Dart! • Uses native WebView iOS: WKWebView Android: android.webkit.WebView • But is it a Widget? The plugin creates the native WebView And renders it in Flutter!

Slide 7

Slide 7 text

Implementation • Not reimplemented in Dart! • Uses native WebView iOS: WKWebView Android: android.webkit.WebView • But is it a Widget? The plugin creates the native WebView And renders it in Flutter!

Slide 8

Slide 8 text

Rendering the Android WebView

Slide 9

Slide 9 text

Working Example

Slide 10

Slide 10 text

Flutter Inspector

Slide 11

Slide 11 text

Flutter Inspector

Slide 12

Slide 12 text

Flutter Inspector

Slide 13

Slide 13 text

Flutter Inspector

Slide 14

Slide 14 text

WebView Rendering on Android AndroidView _AndroidPlatformView RenderAndroidView : RenderBox WebView renders contains … in requires WebViewFactory surface ID contains child PlatformViewController FlutterWebView : PlatformView creates WebViewFlutterPlugin registers Surface WebView contains

Slide 15

Slide 15 text

Rendering the iOS WKWebView

Slide 16

Slide 16 text

WebView Rendering on iOS • Similar to Android • RenderUiKitView will render a surface created in the PlatformViewIOS • Passes an ID

Slide 17

Slide 17 text

Hybrid Composition New in Flutter 1.20!

Slide 18

Slide 18 text

WebView platform Texture rendering (default) •AndroidWebView •CupertinoWebView Hybrid composition •SurfaceAndroidWebView

Slide 19

Slide 19 text

Hybrid Composition SurfaceAndroidWebView PlatformViewRenderBox WebView … requires PlatformViewSurfaceFactory ID contains child creates WebViewFlutterPlugin registers WebView Skia AndroidViewSurface contains

Slide 20

Slide 20 text

WebView Widget

Slide 21

Slide 21 text

WebView Widget • InitialUrl • javaScriptMode • onWebViewCreated • onPageFinished, onPageStarted • gestureRecognizers • navigationDelegate • javaScriptChannels

Slide 22

Slide 22 text

WebView Widget • InitialUrl • javaScriptMode • onWebViewCreated • onPageFinished, onPageStarted • gestureRecognizers • navigationDelegate • javaScriptChannels

Slide 23

Slide 23 text

WebView Widget: initialUrl WebView( initialUrl: “https://www.flutter.dev/", ),

Slide 24

Slide 24 text

WebView Widget • InitialUrl • javaScriptMode • onWebViewCreated • onPageFinished, onPageStarted • gestureRecognizers • navigationDelegate • javaScriptChannels

Slide 25

Slide 25 text

WebView Widget: javaScriptMode WebView( initialUrl: … javascriptMode: JavascriptMode.unrestricted, ),

Slide 26

Slide 26 text

WebView Widget • InitialUrl • javaScriptMode • onWebViewCreated • onPageFinished, onPageStarted • gestureRecognizers • navigationDelegate • javaScriptChannels

Slide 27

Slide 27 text

WebView Widget: onWebViewCreated WebView( initialUrl: … javascriptMode: … onWebViewCreated: (WebViewController controller) { _controller = controller; }, ),

Slide 28

Slide 28 text

WebViewController • loadUrl(String url) • currentUrl() • canGoBack() • canGoForward() • goBack() • goForward() • reload() • clearCache()

Slide 29

Slide 29 text

WebViewController • loadUrl(String url) • currentUrl() • canGoBack() • canGoForward() • goBack() • goForward() • reload() • clearCache()

Slide 30

Slide 30 text

WebViewController: reload onPressed: () async { await _controller.reload(); }

Slide 31

Slide 31 text

WebView Widget • InitialUrl • javaScriptMode • onWebViewCreated • onPageFinished, onPageStarted • gestureRecognizers • navigationDelegate • javaScriptChannels

Slide 32

Slide 32 text

WebView Widget: onPageFinished WebView( initialUrl: … javascriptMode: … onWebViewCreated: … onPageFinished: (url) { // use the URL } ),

Slide 33

Slide 33 text

WebView Widget • InitialUrl • javaScriptMode • onWebViewCreated • onPageFinished, onPageStarted • gestureRecognizers • navigationDelegate • javaScriptChannels

Slide 34

Slide 34 text

WebView Widget • InitialUrl • javaScriptMode • onWebViewCreated • onPageFinished • gestureRecognizers • navigationDelegate • javaScriptChannels The Power of WebViews in Flutter, by Emily Fortuna https:/ /medium.com/flutter-io/the-power-of-webviews-in-flutter- a56234b57df2

Slide 35

Slide 35 text

WebView Widget • InitialUrl • javaScriptMode • onWebViewCreated • onPageFinished, onPageStarted • gestureRecognizers • navigationDelegate • javaScriptChannels

Slide 36

Slide 36 text

WebView Widget: NavigationDelegate WebView( navigationDelegate: (request) { bool isHost = request.url.startsWith( “https://flutter.dev”); if (isHost) return NavigationDecision.navigate; else return NavigationDecision.prevent; } );

Slide 37

Slide 37 text

WebView Widget • InitialUrl • javaScriptMode • onWebViewCreated • onPageFinished, onPageStarted • gestureRecognizers • navigationDelegate • javaScriptChannels

Slide 38

Slide 38 text

WebView Widget: javaScriptChannels WebView( javascriptChannels: {_channel}, );

Slide 39

Slide 39 text

WebView Widget: javaScriptChannels WebView( javascriptChannels: {_channel}, ); var _channel = JavascriptChannel( name: 'LaraDemo', onMessageReceived: (JavascriptMessage message) { print(message.message); });

Slide 40

Slide 40 text

WebView Widget: javaScriptChannels WebView( javascriptChannels: {_channel}, ); var _channel = JavascriptChannel( name: 'LaraDemo', onMessageReceived: (JavascriptMessage message) { print(message.message); });

Slide 41

Slide 41 text

WebView Widget: javaScriptChannels WebView( javascriptChannels: {_channel}, ); var _channel = JavascriptChannel( name: 'LaraDemo', onMessageReceived: (JavascriptMessage message) { print(message.message); });

Slide 42

Slide 42 text

WebView Widget: javaScriptChannels var _channel = JavascriptChannel( name: 'LaraDemo', onMessageReceived: (JavascriptMessage message) { print(message.message); }); Flutter side

Slide 43

Slide 43 text

WebView Widget: javaScriptChannels var _channel = JavascriptChannel( name: 'LaraDemo', onMessageReceived: (JavascriptMessage message) { print(message.message); }); Flutter side LaraDemo.postMessage('Hello'); HTML side

Slide 44

Slide 44 text

Limitations

Slide 45

Slide 45 text

Performance AndroidView is costly

Slide 46

Slide 46 text

Known Issues • Accessibility (Talkback) • Keyboard (can’t change language, hides content) • Text selection (doesn’t respond to touch events, handles not showing on Android) • Text input (passwords) • Animation (is slow on Android, scroll)

Slide 47

Slide 47 text

Hybrid Composition fixes most issues https:/ /github.com/flutter/flutter/issues/61133

Slide 48

Slide 48 text

Hybrid Composition fixes most issues https:/ /github.com/flutter/plugins/pull/2883

Slide 49

Slide 49 text

What’s next

Slide 50

Slide 50 text

Improved Scrolling https:/ /github.com/flutter/plugins/pull/2762

Slide 51

Slide 51 text

Add pinch to zoom for Android https:/ /github.com/flutter/plugins/pull/2451

Slide 52

Slide 52 text

Contributing

Slide 53

Slide 53 text

Contributing

Slide 54

Slide 54 text

Contributing

Slide 55

Slide 55 text

Flutter is open-source. Submit a pull request!

Slide 56

Slide 56 text

56 L a r a M a r t í n F l u t t e r / D a r t G D E A n d r o i d D e v e l o p e r @ L a r i k i Thank You!