【问题标题】:Search text in WebView using Flutter使用 Flutter 在 WebView 中搜索文本
【发布时间】:2020-08-11 02:33:37
【问题描述】:

我目前有一个应用程序,我必须在其中阅读 epub 格式的书籍,我尝试使用 epub_kitty 之类的库,但我在使用其他需要的库时遇到了很多错误。无论如何,我需要我的 Flutter 应用程序在 web 视图中搜索短语,选择(检查)短语供用户稍后打开和查看,并为这本书添加书签。

我目前正在测试的一个选项是获取我的 epub 的 html 部分并使用我的 webview 将其显示给用户,但我不知道如何执行我为应用程序想象的功能(我我目前正在尝试在 html 中进行文本搜索部分,我正在尝试在我的 webview 中使用 javascript 代码,但它不起作用),有什么想法吗?

【问题讨论】:

    标签: javascript flutter pdf webview epub


    【解决方案1】:

    我认为可行的唯一方法是使用 Javascript...这是一个示例

    final Completer<WebViewController> _controller = Completer<WebViewController>();    
    
    Column(
        children: [
            FutureBuilder<WebViewController>(
              future: _controller.future,
              builder: (context, AsyncSnapshot<WebViewController> controller) {
                if (controller.hasData) {
                  return FlatButton(
                      child: Text('Find "information"'),
                      onPressed: () {
                        controller.data.evaluateJavascript('self.find("information")');
                      });
                }
                
                return SizedBox(height: 40);
              },
            ),
            Container(
              height: 400,
              child: WebView(
                initialUrl: 'https://flutter.dev',
                javascriptMode: JavascriptMode.unrestricted,
                onWebViewCreated: (WebViewController webViewController) {
                  _controller.complete(webViewController);
                },
              ),
            )
          ],
        )
    

    如您所见,通过使用evaluateJavascript,您可以运行查找文本所需的代码。至于您需要什么,您可以创建一个更复杂的函数,并在需要时将其添加到您的 html 中。然后你就可以从这里调用它了。

    【讨论】:

    • 非常感谢,这已经是我申请中的一个进步。我阅读了有关 javascript 文档的更多信息,发现此函数无法将单词的位置返回给我,因此我无法让我的用户被带到它,我什至无法保存该单词以供将来搜索。
    • 不确定您是如何对搜索进行编码的,但您可以从那里获取查询以存储给您的用户。如果找到查询,JS 函数会返回 true|false,因此您可以从那里获取它,如果为 true,则找到该单词并存储您在查询中的任何内容。除非你想知道这个词的确切位置?看看this answer
    【解决方案2】:

    您可以使用runJavascriptReturningResultrunJavascript 方法而不是webviewcontroller

    Return true if find a result or false (non-case search)
    
    _controller!.runJavascriptReturningResult("self.find('bootstrap')")
    .then((value) => print(value));
    

    区分大小写的搜索

    _controller!.runJavascript("self.find('Hi',{'CaseSensitive':true})");
    

    语法 window.find(aString, aCaseSensitive, aBackwards, aWrapAround, aWholeWord, aSearchInFrames, aShowDialog);复制到剪贴板 aString 要搜索的文本字符串。

    aCaseSensitive 一个布尔值。如果为真,则指定区分大小写 搜索。

    aBackwards 一个布尔值。如果为 true,则指定向后搜索。

    aWrapAround 一个布尔值。如果为 true,则指定环绕搜索。

    aWholeWord 未实现 一个布尔值。如果为真,则指定一个整体 词搜索。这没有实施;请参阅错误 481513。

    aSearchInFrames 一个布尔值。如果为真,则指定搜索 帧。

    如果找到字符串则返回true;否则为假。

    mdn page

    示例代码

    import 'dart:io';
    
    import 'package:flutter/material.dart';
    import 'package:webview_flutter/webview_flutter.dart';
    
    void main() {
      WidgetsFlutterBinding.ensureInitialized();
    
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(),
            body: Center(
              child: Column(
                children: [
                  Container(
                      child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Row(
                      children: [
                        Expanded(
                          child: TextField(
                            onChanged: (v) {
                              // _controller!
                              //     .runJavascriptReturningResult(
                              //     "self.find('${_textcontrol.text}')")
                              //     .then((value) => print(value));
                            },
                            controller: _textcontrol,
                            decoration: InputDecoration(
                                hintText: 'Search', border: OutlineInputBorder()),
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: Container(
                            height: 55,
                            child: ElevatedButton(
                                onPressed: () {
                                  var casesensitive =
                                      "self.find('${_textcontrol.text}',{'CaseSensitive':true})";
                                  var noncase = "self.find('${_textcontrol.text}')";
                                  _controller!.runJavascript(noncase);
                                  // .then((value) => print(value));
                                },
                                child: Icon(
                                  Icons.search,
                                  size: 45,
                                )),
                          ),
                        )
                      ],
                    ),
                  )),
                  Expanded(
                      child: MyHomePage(
                    title: '',
                  ))
                ],
              ),
            ),
          ),
        );
      }
    }
    
    WebViewController? _controller;
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key? key, required this.title}) : super(key: key);
    
      final String title;
      Color appBarcolor = Colors.blue;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    var _textcontrol = TextEditingController();
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      void initState() {
        super.initState();
    
        if (Platform.isAndroid) WebView.platform = AndroidWebView();
      }
    
      @override
      Widget build(BuildContext context) {
        return controller();
      }
    
      WebView controller() {
        return WebView(
          javascriptMode: JavascriptMode.unrestricted,
          initialUrl: 'https://getbootstrap.com/',
          onWebViewCreated: (WebViewController webViewController) {
            _controller = webViewController;
          },
          navigationDelegate: (NavigationRequest request) {
            setState(() {
              widget.appBarcolor = Colors.black87;
            });
    
            return NavigationDecision.navigate;
          },
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-14
      • 2012-01-25
      • 2018-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多