如何解决Flutter的WebView白屏和视频自动播放

前言

众所周知,Flutter 的 WebView 不太友好,用起来不顺手。 我们 Flutter 开发常用的 WebView 库有2个,一个是 Flutter 官方自己出的 webview_flutter ,另一个是比较流行的 flutter_inappwebview 。这两个库其实差不多,flutter_inappwebview 功能比较丰富,封装了很多事件、方法等,但是很多问题这两个库都会遇到。本文以 webview_flutter 为基础库展开讲解相关问题以及解决方案。

问题

白屏、UI错乱

如上图所示

  • 测试的时候发现部分手机(如OPPO)会出现白屏现象
  • 原生与 Flutter 混编,打开页面会发现页面布局变了,顶部banner变小了

查阅网上的一些解决方案,千篇一律都是:

if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
复制代码

但是,这样设置其实是不对的,还会出现以上问题,真正的解决方案是:

if (Platform.isAndroid) WebView.platform = AndroidWebView();
复制代码

视频自动播放

由于需求需要,打开页面的时候,列表的第一个视频(YouTube/Facebook 视频)需要自动播放。 但是发现没法自动播放,如下图,会出现播放之后马上暂停的现象。

查阅资料得知,是谷歌浏览器的隐私政策导致的。

所以要想视频自动播放,有两种方案:

  • 静音播放。
    • 在 Web 端调用视频播放器的静音即可自动播放。
  • 模拟点击。
    • 给 WebView 设置一个 GlobalKey 。
      WebView(
          key: logic.state.videoGlobalKey,
          ......
        );
      }
      复制代码
    • 然后在 WebView 的 onPageFinished 方法里,通过 GlobalKey 获取 WebView 的位置,从而进行模拟点击,就可以自动播放视频了。
      var currentContext = state.videoGlobalKey.currentContext;
      var offset = (currentContext?.findRenderObject() as RenderBox)
          .localToGlobal(Offset.zero);
      //模拟点击
      var addPointer = PointerAddedEvent(
        pointer: 0,
        position: Offset(
            offset.dx + 92.w,
            offset.dy + 92.w),
      );
      var downPointer = PointerDownEvent(
        pointer: 0,
        position: Offset(
            offset.dx + 92.w,
            offset.dy + 92.w),
      );
      var upPointer = PointerUpEvent(
        pointer: 0,
        position: Offset(
            offset.dx + 92.w,
            offset.dy + 92.w),
      );
      GestureBinding.instance!.handlePointerEvent(addPointer);
      GestureBinding.instance!.handlePointerEvent(downPointer);
      GestureBinding.instance!.handlePointerEvent(upPointer);
      复制代码

这两种方案各有利弊,方案一无法播放声音(需要用户手动点击开启声音),方案二偶尔会有误触的操作。我们 APP 通过与产品商量最终选取的是方案一的解决方案。

另外 iOS 端自动播放会自动全屏,需要设置以下属性:

WebView(
    key: logic.state.videoGlobalKey,
    // 允许在线播放(解决iOS播放视频自动全屏)
    allowsInlineMediaPlayback: true,
    ......
  );
}
复制代码

以下是需求完成的完整效果:

猜你喜欢

转载自juejin.im/post/7102256787117572132
今日推荐