webview_jsbridge 1.0.4 copy "webview_jsbridge: ^1.0.4" to clipboard
webview_jsbridge: ^1.0.4 copied to clipboard

A flutter jsbridge package compatible with webview_flutter, no native dependence.

example/lib/main.dart

import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:local_assets_server/local_assets_server.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_jsbridge/webview_jsbridge.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomeView('es5'),
    );
  }
}

class HomeView extends StatefulWidget {
  final String title;
  HomeView(this.title) : super();

  @override
  _HomeViewState createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  final jsBridge = WebViewJSBridge();

  bool isListening = false;
  String? address;
  int? port;

  @override
  initState() {
    _initServer();
    super.initState();
  }

  Future<void> _initServer() async {
    final server = LocalAssetsServer(
      address: InternetAddress.loopbackIPv4,
      assetsBasePath: 'assets/',
      logger: DebugLogger(),
    );

    final address = await server.serve();

    setState(() {
      this.address = address.address;
      port = server.boundPort!;
      isListening = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: [
          if (widget.title == 'es5')
            TextButton(
              child: Text(
                'es7',
                style: TextStyle(color: Colors.red),
              ),
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (ctx) => HomeView('es7'),
                ),
              ),
            ),
        ],
      ),
      body: isListening
          ? Row(
              children: [
                Expanded(
                  child: _buildWebView(),
                ),
                Expanded(
                  child: Column(
                    children: [
                      Text('native'),
                      TextButton(
                        child: Text(
                          'sendHello',
                        ),
                        onPressed: () => _sendHello(),
                      ),
                      TextButton(
                        child: Text(
                          'callJSEcho',
                        ),
                        onPressed: () => _callJSEcho(),
                      ),
                      TextButton(
                        child: Text(
                          '_callNotExist',
                        ),
                        onPressed: () => _callNotExist(),
                      ),
                    ],
                  ),
                ),
              ],
            )
          : Center(child: CircularProgressIndicator()),
    );
  }

  WebView _buildWebView() {
    final isEs5 = widget.title == 'es5';
    final jsVersion =
        isEs5 ? WebViewInjectJsVersion.es5 : WebViewInjectJsVersion.es7;
    final htmlVersion = isEs5 ? 'default' : 'async';
    return WebView(
      javascriptChannels: jsBridge.jsChannels,
      // must enable js
      javascriptMode: JavascriptMode.unrestricted,
      onWebViewCreated: (controller) {
        jsBridge.controller = controller;
        jsBridge.defaultHandler = _defaultHandler;
        jsBridge.registerHandler("NativeEcho", _nativeEchoHandler);
      },
      navigationDelegate: (NavigationRequest navigation) {
        print('navigationDelegate ${navigation.url}');
        // this is no effect on Android
        if (navigation.url.contains('__bridge_loaded__')) {
          jsBridge.injectJs(esVersion: jsVersion);
          return NavigationDecision.prevent;
        }
        return NavigationDecision.navigate;
      },
      onPageFinished: (String url) {
        jsBridge.injectJs(esVersion: jsVersion);
      },
      initialUrl: 'http://$address:$port/$htmlVersion.html',
    );
  }

  Future<void> _sendHello() async {
    final res = await jsBridge.send('hello from native');
    print('_sendHello res: $res');
  }

  Future<void> _callJSEcho() async {
    final res =
        await jsBridge.callHandler('JSEcho', data: 'callJs from native');
    print('_callJSEcho res: $res');
  }

  Future<void> _callNotExist() async {
    final res =
        await jsBridge.callHandler('NotExist', data: 'callJs from native');
    print('_callNotExist res: $res');
  }

  Future<Object?> _defaultHandler(Object? data) async {
    await Future.delayed(Duration(seconds: 1), () {});
    return '_defaultHandler res from native';
  }

  Future<Object?> _nativeEchoHandler(Object? data) async {
    await Future.delayed(Duration(seconds: 1), () {});
    return '_nativeEchoHandler res from native';
  }
}
2
likes
100
pub points
44%
popularity

Publisher

unverified uploader

A flutter jsbridge package compatible with webview_flutter, no native dependence.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (LICENSE)

Dependencies

flutter, webview_flutter

More

Packages that depend on webview_jsbridge