Flutter Webview - захват событий сенсорного запуска на Android - PullRequest
2 голосов
/ 08 апреля 2020

Эта проблема , опубликованная на Github, кажется, предполагает, что touch events намеренно подавлена ​​в реализации Android, якобы для включения обнаружения longpresses в целях копирования / вставки.

Мое собственное приложение должно иметь возможность перехватывать события касания - и выбор текста в длинном нажатии не имеет никакого отношения вообще. Я думал, что сделаю это, используя локальную копию кода реализации Flutter webview , а затем подавив фильтр 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 root. После изменения pubspec.yaml для чтения

  webview_flutter:
    path: ../../webview_flutter

и запуска flutter clean && flutter run APK был собран и установлен на моем тестовом устройстве. Однако затем он сообщил

Настройка FlutterEngine. D / FlutterActivityAndFragmentDelegate (24999): не был предоставлен предпочтительный FlutterEngine. Создание нового FlutterEngine для этого FlutterFragment. W / FlutterEngine (24999): попытался автоматически зарегистрировать плагины в FlutterEngine (io.flutter.embedding.engine. FlutterEngine@9480b1a), но не смог найти и вызвать GeneratedPluginRegistrant.

Я не понимаю этого сообщение. Я был бы очень признателен всем, кто мог бы рассказать мне, как / можно ли это исправить.

Ответы [ 2 ]

0 голосов
/ 26 апреля 2020

Вот то, что я нашел: насколько я могу судить, официальное веб-представление Flutter - заброшенный шаг. Есть ошибки, датируемые три года назад, которым уделяется мало внимания. Некоторые из его «функций», такие как longPress подавление / обнаружение, просто смешны.

Я перешел на использование Flutter Webview plugin , который исправляет большинство проблем, с которыми я столкнулся. Просто не забудьте включить withzoom:true. Я обнаружил, что веб-просмотр автоматически не перехватывает события onPause и onResume. Я обработал это следующим образом

 @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 singleton
  • В вашем Javascript вы определили callBack

Я должен упомянуть, что я начинаю с WidgetsApp и приведенный выше код находится в классе с сохранением состояния, который используется с with WidgetsBindingObserver

0 голосов
/ 08 апреля 2020

Я теперь случайно наткнулся на выход из проблемы "нет событий касания в Android", которую пёс Flutter Webview. Вместо того чтобы удалять мой вопрос, я чувствовал, что для других было бы более полезно оставить его здесь с решением, которое я нашел.

Я начал с намерения отлавливать события Touch в Flutter, а затем передавать их в WebView через evaluateJavascript. Для этого я изменил структуру своего виджета, чтобы обернуть WebView в слушатель. Весь мой код конструктора виджетов показан ниже.

@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. Мне непонятно, почему это должно происходить - возможно, кто-то еще здесь может объяснить.

Несколько замечаний по моему коду выше

  • Я использую WebViews, которые занимают все устройство экран в альбомном формате - как на iOS, так и на Android
  • Я использую WidgetsApp вместо MaterialApp для предоставления базовых c скаффолдингов
  • SafeArea гарантирует, что приложение занимает пространство, которое
  • Слушатель - это то, что делает волхв c здесь и делает сенсорные события доступными в WebView, даже на Android
  • WebView является основным игроком, где происходят все действия , В переднем конце JavaScript вам просто нужно захватить события touchstart, touchmove и touchend на document.body.

. Вы можете прочитать больше о различных виджетах, которые я использовал здесь, в документах по флаттеру .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...