Flutter网页交互插件mix_web_bridge的使用

MixWebBridge 是一个基于 webview_flutter 的 Flutter 插件,用于在 Flutter 应用中实现网页与原生代码之间的桥接。

开始使用

添加依赖

pubspec.yaml 文件中添加以下依赖:

dependencies:
  mix_web_bridge: ^1.0.0

然后运行 flutter pub get 来安装依赖。

简单使用

以下是一个简单的示例,展示如何加载一个网页并使用 $app 对象进行通信。

import 'package:mix_web_bridge/mix_web_bridge.dart';

Navigator.of(context).push(CupertinoPageRoute(
  builder: (context) => const MixWebView(url: "https://www.google.com"),
));

在 JavaScript 中,你可以通过 $app 对象调用 Flutter 方法:

const world = await $app.hello({message: "world"});
console.log(world);
// {message: "world"}

高级使用

创建自定义的 WebView

创建一个自定义的 WebView,并在页面加载完成后执行一些 JavaScript 操作。

import 'package:webview_flutter/webview_flutter.dart';
import 'package:mix_web_bridge/mix_web_bridge.dart';

class Web extends StatefulWidget {
  final String? url;
  const Web({this.url, Key? key}) : super(key: key);

  [@override](/user/override)
  _WebState createState() => _WebState();
}

class _WebState extends MixWebViewState<Web> {
  String _title = "";
  late final Widget webView = buildWebView(url: widget.url);

  [@override](/user/override)
  void onWebViewPageFinished(String url) async {
    // 获取网页的标题
    final title = await bridgeManager.runJs("document.title") ?? "";
    setState(() {
      _title = title.replaceAll("\"", "");
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return _AppPage(
      title: _title,
      child: webView,
    );
  }
}

使用路由映射

将路由映射添加到应用中,并监听导航事件。

final Map<String, WidgetBuilder> _routes = {
  '/': (contxt) => const Home(),
  '/web': (context) {
    final args = ModalRoute.of(context)?.settings.arguments as Map<String, dynamic>? ?? {};
    final url = args["url"] as String? ?? null;
    return Web(url: url);
  },
};

[@override](/user/override)
Widget build(BuildContext context) {
  return CupertinoApp(
    navigatorObservers: [mwbRouteObserver],
    title: 'App',
    routes: _routes,
    supportedLocales: const [Locale('en', '')],
  );
}

在 JavaScript 中,可以使用 $app.route 进行页面跳转或返回操作:

// 跳转到首页
$app.route({name: "/"});

// 跳转到另一个网页
$app.route({name: "/web", data: {url: "https://www.google.com"}});

// 返回上一页
$app.route({pop: true});

内置桥接

hello

参数

参数名 类型 是否必需 备注
message string Y 问候消息

返回值

名称 类型 备注
message string
const world = await $app.hello({message: "world"});
console.log(world);
// {message: "world"}

route

参数

参数名 类型 是否必需 备注
name string N 路由名称
data object N 路由参数
pop bool N 是否返回上一页

返回值

无返回值

// 跳转到首页
$app.route({name: "/"});

// 跳转到另一个网页
$app.route({name: "/web", data: {url: "https://www.google.com"}});

// 返回上一页
$app.route({pop: true});

事件

监听应用的生命周期事件:

const eventId = $app.on("pageAppear", () => {
  console.log("page appear");
});

$app.on("pageDisappear", () => {
  console.log("page disappear");
});

$app.on("appResumed", () => {
  console.log("app resumed");
});

$app.on("appPaused", () => {
  console.log("app paused");
});

// 移除事件
eventId && $app.removeEvent(eventId);

自定义桥接

创建一个自定义桥接类并扩展 MixWebBridge

class MyBridge extends MixWebBridge {
  /// 定义自定义方法
  MWBResponse myHelloHandle(MWBParams params) {
    final name = mwbConvert<String>(params["name"]) ?? "";
    return {"message": "hello $name"};
  }

  /// 绑定方法
  [@override](/user/override)
  MWBHandleMap handleMap() {
    return {"helloWorld": myHelloHandle};
  }

  /// 在页面加载时注入 JavaScript
  [@override](/user/override)
  String injectJavascript() {
    return 'localStorage.token = "mytoken";';
  }
}

在 JavaScript 中使用自定义桥接方法:

console.log(localStorage.token);
// mytoken

const msg = await $app.helloWorld({name: "Eric"});
console.log(msg);
// {message: "hello Eric"}

示例代码

以下是完整的示例代码:

import 'package:flutter/cupertino.dart';
import 'package:mix_web_bridge/mix_web_bridge.dart';

class MyBridge extends MixWebBridge {
  [@override](/user/override)
  MWBHandleMap handleMap() {
    return {};
  }

  [@override](/user/override)
  String injectJavascript() {
    return 'localStorage.token = "0330qr5kidw51ob03h9rbp7zc6n83d8m";';
  }
}

void main() async {
  MixWebBridgeManager.setup(
    bridges: [MyBridge()],
  );
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);

  final Map<String, WidgetBuilder> _routes = {
    '/': (contxt) => const Home(),
    '/web': (context) {
      final args = ModalRoute.of(context)?.settings.arguments as Map<String, dynamic>? ?? {};
      final url = args["url"] as String? ?? null;
      return Web(url: url);
    },
  };

  [@override](/user/override)
  Widget build(BuildContext context) {
    return CupertinoApp(
      navigatorObservers: [mwbRouteObserver],
      title: 'App',
      routes: _routes,
      supportedLocales: const [Locale('en', '')],
    );
  }
}

/// Home
class Home extends StatelessWidget {
  const Home({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return _AppPage(
      title: "Home",
      child: CupertinoButton(
        child: const Text("Push webview"),
        onPressed: () {
          Navigator.of(context).pushNamed("/web");
        },
      ),
    );
  }
}

/// Web
class Web extends StatefulWidget {
  final String? url;
  const Web({this.url, Key? key}) : super(key: key);

  [@override](/user/override)
  _WebState createState() => _WebState();
}

class _WebState extends MixWebViewState<Web> {
  String _title = "";
  late final Widget webView = buildWebView(url: widget.url);

  [@override](/user/override)
  void onWebViewPageFinished(String url) async {
    final title = await bridgeManager.runJs("document.title") ?? "";
    setState(() {
      _title = title.replaceAll("\"", "");
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return _AppPage(
      title: _title,
      child: webView,
    );
  }
}

/// App Page
class _AppPage extends StatelessWidget {
  const _AppPage({Key? key, required this.title, required this.child}) : super(key: key);
  final String title;
  final Widget child;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(middle: Text(title)),
      backgroundColor: const Color.fromRGBO(247, 247, 247, 1),
      resizeToAvoidBottomInset: true,
      child: Container(
        padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top + 44),
        child: child,
      ),
    );
  }
}

更多关于Flutter网页交互插件mix_web_bridge的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网页交互插件mix_web_bridge的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


mix_web_bridge 是一个用于在 Flutter 应用中实现与 Web 页面交互的插件。它允许 Flutter 应用与嵌入的 WebView 进行双向通信,从而实现 Flutter 与 JavaScript 之间的数据传递和功能调用。

安装 mix_web_bridge

首先,你需要在 pubspec.yaml 文件中添加 mix_web_bridge 依赖:

dependencies:
  flutter:
    sdk: flutter
  mix_web_bridge: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 来安装依赖。

基本用法

1. 在 Flutter 中初始化 MixWebBridge

在你的 Flutter 应用中,首先需要初始化 MixWebBridge,并设置与 WebView 的通信。

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: WebViewExample(),
    );
  }
}

class WebViewExample extends StatefulWidget {
  [@override](/user/override)
  _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  late MixWebBridge _mixWebBridge;

  [@override](/user/override)
  void initState() {
    super.initState();
    _mixWebBridge = MixWebBridge();
    _mixWebBridge.init();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('MixWebBridge Example'),
      ),
      body: WebView(
        initialUrl: 'https://your-web-page.com',
        javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (WebViewController webViewController) {
          _mixWebBridge.setWebViewController(webViewController);
        },
        javascriptChannels: <JavascriptChannel>{
          _mixWebBridge.javascriptChannel,
        },
      ),
    );
  }
}

2. 在 Web 页面中使用 MixWebBridge

在 Web 页面中,你需要引入 mix_web_bridge.js 文件,并使用它来与 Flutter 进行通信。

<!DOCTYPE html>
<html>
<head>
  <title>WebView Example</title>
  <script src="mix_web_bridge.js"></script>
</head>
<body>
  <h1>Hello, Flutter!</h1>
  <button onclick="sendMessageToFlutter()">Send Message to Flutter</button>

  <script>
    function sendMessageToFlutter() {
      MixWebBridge.sendMessage('Hello from Web!');
    }

    MixWebBridge.registerHandler('fromFlutter', function(message) {
      console.log('Received message from Flutter:', message);
    });
  </script>
</body>
</html>

3. 在 Flutter 中接收来自 Web 的消息

你可以在 Flutter 中注册一个处理程序来接收来自 Web 的消息。

_mixWebBridge.registerHandler('fromWeb', (message) {
  print('Received message from Web: $message');
});

4. 从 Flutter 发送消息到 Web

你也可以从 Flutter 发送消息到 Web 页面。

_mixWebBridge.sendMessage('Hello from Flutter!');

完整示例

以下是一个完整的示例,展示了如何在 Flutter 和 Web 页面之间进行双向通信。

import 'package:flutter/material.dart';
import 'package:mix_web_bridge/mix_web_bridge.dart';
import 'package:webview_flutter/webview_flutter.dart';

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: WebViewExample(),
    );
  }
}

class WebViewExample extends StatefulWidget {
  [@override](/user/override)
  _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  late MixWebBridge _mixWebBridge;

  [@override](/user/override)
  void initState() {
    super.initState();
    _mixWebBridge = MixWebBridge();
    _mixWebBridge.init();

    _mixWebBridge.registerHandler('fromWeb', (message) {
      print('Received message from Web: $message');
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('MixWebBridge Example'),
      ),
      body: Column(
        children: [
          Expanded(
            child: WebView(
              initialUrl: 'https://your-web-page.com',
              javascriptMode: JavascriptMode.unrestricted,
              onWebViewCreated: (WebViewController webViewController) {
                _mixWebBridge.setWebViewController(webViewController);
              },
              javascriptChannels: <JavascriptChannel>{
                _mixWebBridge.javascriptChannel,
              },
            ),
          ),
          ElevatedButton(
            onPressed: () {
              _mixWebBridge.sendMessage('Hello from Flutter!');
            },
            child: Text('Send Message to Web'),
          ),
        ],
      ),
    );
  }
}
回到顶部