Flutter webview 文本输入被软键盘隐藏

Era*_*ore 5 webview android-softkeyboard flutter

我正在 Android 上进行测试(我将验证它在 iOS 上是否也相同)。

我的问题是,当我有一个显示条纹结帐页面的网页视图,并且我点击那里的文本条目以输入靠近底部(邮政编码)的内容时,虚拟键盘会覆盖网页视图,即使在网页视图。

看起来 webview 按预期占据了整个屏幕,但是当软键盘出现时 Flutter 我认为通常会为其腾出空间(缩小屏幕上显示的小部件)。Webview 似乎保持相同的大小。

我尝试了一种将网络视图放入具有动态高度的容器()中的技巧。它有点有效。代码如下,关键行是Container()的高度:

height: MediaQuery.of(context).size.height * (MediaQuery.of(context).viewInsets.bottom != 0 ? .7 : 1)
Run Code Online (Sandbox Code Playgroud)

但这会导致键盘混乱。例如,它以某种方式欺骗键盘不输入邮政编码的数字输入类型。它看起来像是在尝试,但在一瞬间就重新绘制到非数字键盘。

为什么Webview不支持手机上的软键盘?

这是我在有状态小部件中的构建:

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Stack(
        children: [
          initialUrl == null
              ? Container()
              : Container(
                  height: MediaQuery.of(context).size.height * (MediaQuery.of(context).viewInsets.bottom != 0 ? .7 : 1),
                  child: WebView(
                    initialUrl: initialUrl,
                    javascriptMode: JavascriptMode.unrestricted,
                    onPageStarted: (controller) {},
                    onPageFinished: (controller) {
                      Future.delayed(Duration(milliseconds: 1234), () {
                        if (mounted) {
                          showLoading = false;
                          setState(() {});
                        }
                      });
                    },
                    navigationDelegate: (NavigationRequest request) {
                      if (request.url.startsWith('https://example.com/success')) {
                        Navigator.of(context).pop('success');
                      } else if (request.url.startsWith('https://example.com/cancel')) {
                        Navigator.of(context).pop('cancel');
                      }
                      return NavigationDecision.navigate;
                    },
                  ),
                ),
          showLoading == true
              ? Center(
                  child: Container(width: 80, height: 80, child: CircularProgressIndicator()),
                )
              : Container(),
        ],
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

这是屏幕截图。请注意,在键盘中,您甚至无法滚动网络视图来查看您正在输入的 zip...

在此输入图像描述 在此输入图像描述

Era*_*ore 11

对我来说,答案有两件事。

首先使用这一行,它设置WebView.platform在显示 web 视图的有状态小部件内。请注意,这是我当时在 Android 上进行的测试所特有的,所以也许对于你们中的一些人来说,当您没有看到该问题时,您可能是在 iOS 上?

  @override
  void initState() {
    super.initState();
    if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView(); // <<== THIS
  }
Run Code Online (Sandbox Code Playgroud)

其次,我添加了一个设置为 true 的脚手架resizeToAvoidBottomInset,并删除了对此的使用:

height: MediaQuery.of(context).size.height * (MediaQuery.of(context).viewInsets.bottom != 0 ? .7 : 1),`
Run Code Online (Sandbox Code Playgroud)

这是带有 webview 的 body 的代码

@override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Stack(
        children: [
          initialUrl == null
              ? Container()
              : Scaffold(
                resizeToAvoidBottomInset: true,
                body: WebView(
                  initialUrl: initialUrl,
                  javascriptMode: JavascriptMode.unrestricted,
                  onPageStarted: (controller) {},
                  onPageFinished: (controller) {
                    Future.delayed(Duration(milliseconds: 1234), () {
                      if (mounted) {
                        showLoading = false;
                        setState(() {});
                      }
                    });
                  },
                  navigationDelegate: (NavigationRequest request) {
                    if (request.url.startsWith('https://example.com/success')) {
                      Navigator.of(context).pop('success');
                    } else if (request.url.startsWith('https://example.com/cancel')) {
                      Navigator.of(context).pop('cancel');
                    }
                    return NavigationDecision.navigate;
                  },
                ),
              ),
          showLoading == true
              ? Center(
                  child: Container(width: 80, height: 80, child: CircularProgressIndicator()),
                )
              : Container(),
        ],
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)