Flutter Web: 如何在页面中使用web原生组件及交互

简介: flutter开发经常会与原生打交道,flutter web也一样,尤其在web开发时,因为flutter web还不成熟,第三方库缺少,很多功能需要依靠web原生来实现,比如音视频,录音等等。用视频举例,需要用html和js来实现一个视频播放器,然后在flutter页面中使用这个播放器,这如何来实现?

前言


flutter开发经常会与原生打交道,flutter web也一样,尤其在web开发时,因为flutter web还不成熟,第三方库缺少,很多功能需要依靠web原生来实现,比如音视频,录音等等。用视频举例,需要用html和js来实现一个视频播放器,然后在flutter页面中使用这个播放器,这如何来实现?


flutter使用web原生组件


我们用HtmlElementView来实现,它就是flutter提供的可以在flutter中嵌入html element的widget,我们看如何使用。

先看一个简单的例子:


import 'dart:html';
import 'dart:js' as js;
import 'dart:ui' as ui;
import 'package:flutter/widgets.dart';
class WebTest extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    IFrameElement frame = IFrameElement()
      ..width = '640'
      ..height = '360'
      ..src = 'https://www.baidu.com'
      ..style.border = 'none';
    ui.platformViewRegistry.registerViewFactory(
        'hello-world-html',
            (int viewId) => frame);
    return HtmlElementView(viewType: 'hello-world-html');
  }
}
复制代码


这个组件就是嵌入了一个IFrameElement,里面加载了一个web页面,然后可以将这个组件放到flutter的页面中,这样就可以在任意位置显示这个web页面。

所以可以看到大致就是三个步骤:


  • 创建一个HtmlElement(IFrameElement就是它的子类,另外还有DivElement、ScriptElement等等,后面会提到),将web的内容放入HtmlElement
  • 通过ui.platformViewRegistry.registerViewFactory注册HtmlElement
  • 使用HtmlElementView,通过viewType加载HtmlElement即可


上面只是直接打开了一个页面,那么如果想使用一个web组件如何处理?

这时候就需要使用到HtmlElement的其他子类,并且可能同时用到多个,如下:


import 'dart:html';
import 'dart:js' as js;
import 'dart:ui' as ui;
import 'package:flutter/widgets.dart';
class WebTest extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    DivElement frame = DivElement();
    //设置样式
    StyleElement styleElement = StyleElement();
    styleElement.type = "text/css";
    styleElement.innerHtml = """
      html,
      body {
          height: 100%
      }
      .view-video {
          width: 100%;
          height: 100%;
          background-color: black;
      }
      """;   //这里css样式
    frame.append(styleElement);   //添加到div中
    //引入我们写好的web视频播放器
    DivElement divElement = DivElement();
    divElement.id = "remote_video";
    divElement.className = "view-video";
    frame.append(divElement);    
    //添加js代码,初始化之类的
    ScriptElement scriptElement = new ScriptElement();
    script = """
      var rtcParams = {
        codec: "h264",
        appID: "${config.appId}",
        channel: "${config.channel}",
        token: "${config.token}",
        element: "remote_video"
      };
      var jsCallMethodLeave = function() {
        leave(rtc)
      }
      function doInit() {
        ...
      }
      doInit();
    """;
    scriptElement.innerHtml = script;
    frame.append(scriptElement);
    //最后注册使用
    ui.platformViewRegistry.registerViewFactory(
        'videoplayer',
            (int viewId) => frame);
    return HtmlElementView(viewType: 'hello-world-html');
  }
}
复制代码


可以看到其实也是那三步,只是第一步创建HtmlElement复杂了一些,我们通过各种HtmlElement的子类组合出来一个而已。


动态创建web组件


上面创建的web组件有一个问题,因为我们的播放器初始化的时候需要一个参数,而其中部分参数是可变的,比如:


channel: "${config.channel}",
复制代码


这里的${config.channel}就是使用flutter代码中的config.channel。但是我们使用的时候发现,无论我们怎么重新创建WebTest这个组件(用不同的参数),我们使用的一直都是第一次创建这个组件的参数。也就是说后续的创建其实没有创建而是直接复用?

这个问题就出现在注册上,通过

ui.platformViewRegistry.registerViewFactory注册后,再次注册同样的viewType就不再更新,不是没有创建,而是HtmlElementView使用的一直都是最初注册的那个。


解决这个问题就是使用动态的viewType,比如加入时间戳,如下:

String _divId = "videoplayer" + DateTime.now().toIso8601String();
ui.platformViewRegistry.registerViewFactory(
        _divId,
            (int viewId) => frame);
return HtmlElementView(viewType: _divId);
复制代码


这样就会每次使用最新参数创建的组件。


js执行问题

因为注册的问题其实会导致另外一个小问题,就是js的执行。如果viewType是固定的,那么这个web组件其实只初始化一次,所以js代码中的doinit()也只执行一次,无论在新的页面创建新的WebTest组件,最终使用的都是一个HtmlElement,所以如果在doinit()中打印了相关信息,可以看到后面再次创建或使用就不再打印了。

而使用动态viewType就不再有这样的问题,每次都会重新执行js。


交互


这种嵌入的web组件也会有与flutter进行交互的需求。

这个交互其实根flutter与js的交互是一样的,因为这时候的页面里也加载了这个组件的相关js文件(包括我们自己定义的ScriptElement),所以通过js.context.callMethod("xxx");js.context["xxx"] = function;这种方式即可实现交互,比如:


js.context.callMethod("jsCallMethodLeave");
复制代码


在flutter代码中调用js中的jsCallMethodLeave函数(前面我们自己定义)。

比如:


js.context["webEvent"] = webEvent;
复制代码


在flutter中为js注册一个回调webEvent函数,这样在js中就可以通过window.parent.webEvent(xxx);这种方式回调到flutter的webEvent函数中,实现了js与flutter的通信。

注意js中同名函数的问题,比如上面我们自己定义的jsCallMethodLeave就是为了防止与组件自带的js文件中的函数同名而导致调用失败(找不到函数等问题)


目录
打赏
0
0
0
0
7
分享
相关文章
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
396 4
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
163 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
123 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
90 18
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
97 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
34 0
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
PHP与Ajax在Web开发中的交互技术。PHP作为服务器端脚本语言,处理数据和业务逻辑
本文深入探讨了PHP与Ajax在Web开发中的交互技术。PHP作为服务器端脚本语言,处理数据和业务逻辑;Ajax则通过异步请求实现页面无刷新更新。文中详细介绍了两者的工作原理、数据传输格式选择、具体实现方法及实际应用案例,如实时数据更新、表单验证与提交、动态加载内容等。同时,针对跨域问题、数据安全与性能优化提出了建议。总结指出,PHP与Ajax的结合能显著提升Web应用的效率和用户体验。
95 3
11 Web交互知识你了解吗?
路老师带你深入PHP世界,纯干货分享。本文从Web工作原理讲起,介绍了HTTP协议和Web数据处理流程,重点讲解了PHP如何获取表单数据,包括POST和GET方法的具体实现及示例代码。适合初学者入门,助你掌握PHP核心技术。
44 1
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
在Web开发中,前后端的高效交互是提升用户体验的关键。本文通过一个基于Flask框架的博客系统实战案例,详细介绍了如何使用AJAX和Fetch API实现不刷新页面查看评论的功能。从后端路由设置到前端请求处理,全面展示了这两种技术的应用技巧,帮助Python Web开发者提升项目质量和开发效率。
93 1
Flutter&鸿蒙next中封装一个列表组件
Flutter&鸿蒙next中封装一个列表组件
72 0

热门文章

最新文章

  • 1
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    16
  • 2
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    8
  • 3
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    28
  • 4
    零基础构建即时通讯开源项目OpenIM移动端-Flutter篇
    12
  • 5
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
    2
  • 6
    flutter3-dart3-dymall原创仿抖音(直播+短视频+聊天)商城app系统模板
    7
  • 7
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    3
  • 8
    flutter3-wetrip跨平台自研仿携程app预约酒店系统模板
    9
  • 9
    通过外部链接启动 Flutter App(详细介绍及示例)
    8
  • 10
    部署使用 CHAT-NEXT-WEB 基于 Deepseek
    141
  • AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等