Flutter Webview-在Android上捕获touchstart事件

时间:2020-04-08 11:37:07

标签: android flutter webview long-press touchstart

此发布在Github上的issue似乎暗示touch events在Android实现中被故意抑制,表面上是为了复制/粘贴目的而能够检测到longpresses

我自己的应用程序绝对需要能够捕获触摸事件-长按文本选择没有任何意义。我以为可以通过使用Flutter webview implementation code的本地副本,然后取消longpress过滤器来做到这一点。 webview_android.dart中的相关代码为

我们通过拦截长按事件来防止文本选择。 由于Android上的文本选择问题,这是一个暂时的制止间隙: https://github.com/flutter/flutter/issues/24585-文本选择 对话框未响应触摸事件。 https://github.com/flutter/flutter/issues/24584-文字选择 手柄未显示。 TODO(amirh):在解决上述问题后,请删除此内容。 onLongPress:(){},

为此,我下载了Flutter源文件,并确保webview_flutter在名为Flutter项目根文件夹下两个级别的文件夹中可用。修改pubspec.yaml以便阅读

之后
  webview_flutter:
    path: ../../webview_flutter

并运行flutter clean && flutter run,该APK已构建并安装在我的测试设备上。但是,它随后报告了

设置FlutterEngine。 D / FlutterActivityAndFragmentDelegate(24999):未提供首选的FlutterEngine。创建一个新的 FlutterFragment的FlutterEngine。 W / FlutterEngine(24999):尝试自动向FlutterEngine注册插件 (io.flutter.embedding.engine.FlutterEngine@9480b1a),但找不到并调用 GeneratedPluginRegistrant。

我不明白此消息。那些能够告诉我如何/是否可以修复的人将是我的最大义务。

2 个答案:

答案 0 :(得分:0)

我现在不小心偶然发现了解决Flutter Webview的“ Android中的非接触事件”问题的方法。与其删除我的问题,不如让我将找到的解决方案留在这里对其他人来说更有用。

我开始的目的是自己在Flutter中捕获Touch事件,然后通过evaluateJavascript将它们传输到WebView。为此,我更改了Widget结构,以便将WebView包装在侦听器中。我的整个Widget构建器代码如下所示。

@override Widget build(BuildContext context) 
{
 SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);   

 return WidgetsApp
 (
  onGenerateRoute:makeWebView,
  color:Color.fromRGBO(0,128,255,1.0)
 );
} 


Route makeWebView(RouteSettings settings)
{
 return new PageRouteBuilder
 (
  pageBuilder:(BuildContext context,Animation<double> animation,Animation<double> 
  secondaryAnimation)
  {
   return SafeArea
   (
    child:Listener
    (
     child: SizedBox.expand
     (
      child:WebView
      (
       debuggingEnabled:true, 
       initialUrl:'',
       javascriptMode:JavascriptMode.unrestricted,
       onWebViewCreated:registerController,
       javascriptChannels:Set.from
       ([JavascriptChannel(name:'JSBridge',onMessageReceived:handleMessage)]),
      ),
     ),
    )
   );
  });
 }

让我感到惊讶的是,仅仅这样做就使经过加密的Flutter WebView能够响应touch#事件而不会遇到麻烦的LongPress问题。我不清楚为什么会发生这种情况-也许这里的其他人可以解释。

关于我上面的代码的几点说明

  • 我使用的WebView以横向格式占据整个设备屏幕-在iOS和Android上
  • 我使用WidgetsApp而不是MaterialApp提供基本的脚手架
  • SafeArea确保应用程序消耗合法可用的空间
  • 侦听器是这里的神奇之处,它甚至可以在WebView中使Touch事件可用,即使在Android上也是如此
  • WebView是执行所有操作的主要参与者。在前端JavaScript中,您只需要捕获touchstart上的touchmovetouchenddocument.body事件。

您可以在Flutter Docs上阅读我在这里使用过的各种小部件的更多信息。

答案 1 :(得分:0)

这就是我所发现的:据我所知,Flutter的官方Webview是一个被忽略的继子。有些bug可以追溯到3年,但鲜有受到关注。它的某些“功能”,例如longPress抑制/检测,完全是荒谬的。

我改用Flutter Webview plugin来解决我遇到的大多数问题。只要记住启用withzoom:true。我发现Web视图不会自动捕获onPauseonResume事件。我的处理方法如下

 @override void didChangeAppLifecycleState(AppLifecycleState state) 
 {
  setState(() 
  {
   appState = state;
   switch(state)
   {
    case AppLifecycleState.inactive:
    case AppLifecycleState.paused:
         FlutterWebviewPlugin.evalJavascript('callBack()');break;//onPause
    case AppLifecycleState.resumed:
         FlutterWebviewPlugin.evalJavascript('callBack()');break;//onResume 
   }
  });
 }

您必须确保

  • 您有一个FlutterWebviewPlugin单例的适当初始化的实例
  • 在Javascript中,您定义了callBack

我应该提到我是从WidgetsApp开始的,上面的代码在它与with WidgetsBindingObserver一起使用的有状态类中