【问题标题】:Flutter webview text input gets hidden by soft keyboardFlutter webview文本输入被软键盘隐藏
【发布时间】:2021-07-20 23:44:41
【问题描述】:

我正在 Android 上进行测试(我会验证它在 iOS 上也一样)。

我的问题是,当我有一个显示条纹结帐页面的 web 视图时,我点击那里的文本条目以在底部附近输入一些内容(邮政编码),然后虚拟键盘覆盖了 web 视图,我无法向上滚动甚至在 webview 中。

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

我自己尝试将 Web 视图放入具有动态高度的 container() 中。它有点工作。代码如下,关键是Container()的这个高度:

height: MediaQuery.of(context).size.height * (MediaQuery.of(context).viewInsets.bottom != 0 ? .7 : 1)

但这有混淆键盘的问题。例如,它以某种方式欺骗键盘,使其不是邮政编码的数字输入类型。它看起来像是在尝试,但在一瞬间后重新绘制到非数字键盘。

为什么 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(),
        ],
      ),
    );
  }

这里是屏幕截图。请注意,在键盘上,您甚至无法滚动 web 视图以查看您正在输入的 zip...

【问题讨论】:

    标签: flutter webview android-softkeyboard


    【解决方案1】:

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

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

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

    其次,我添加了一个 resizeToAvoidBottomInset 设置为 true 的 Scaffold 并删除了我对它的使用:

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

    这是带有 webview 的正文的代码

    @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(),
            ],
          ),
        );
      }
    

    【讨论】:

      【解决方案2】:

      您是否尝试过使用 SingleChildScrollView 包装您的小部件?

      【讨论】:

      • 是的,我试过了。它会导致渲染问题,因为 webview 受到无限(未)约束。我想我可以尝试将其放入屏幕大小的容器中,然后放入 SingeChildScrollView。
      • 也许您也可以使用列而不是具有特定高度的容器。
      • 不幸的是,它没有帮助。还有一个 31 像素的溢出,我猜这是由 SafeArea() 引起的。
      • 它对我有用,我发布了代码作为更好的代码格式的答案;)
      【解决方案3】:

      这对我有用:

      Scaffold(
            body: Stack(
              children: [
                //... widgets that render behind the column
                Align(
                  alignment: Alignment.center,
                  child: SingleChildScrollView( 
                    child: Column(
                       children: [
                          //... login form inputs and buttons
                       ]
                    ),
                  ),
                ),
              ],
            ),
          );
      

      【讨论】:

      • 你用 Webview 试过这个吗?你指的是哪个网站?您能否展示一张显示键盘的网页图片,以便我可以看到它是否正常工作?
      【解决方案4】:

      这是一种更简单的方法,即使用“gestureRecognizers”属性将滚动手势移动到 Webview 本身:

      import 'package:flutter/foundation.dart';
      import 'package:flutter/gestures.dart';
      import 'package:flutter/material.dart';
      import 'package:webview_flutter/webview_flutter.dart';
      
      void main() {
        runApp(MyApp());
      }
      
      class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            title: 'Webview Example',
            home: Scaffold(
              appBar: AppBar(
                title: Text('Webview Example'),
              ),
              body: Stack(
                children: [
                  //... widgets that render behind the column
                  WebView(
                    initialUrl: 'https://inputtypes.com',
                    javascriptMode: JavascriptMode.unrestricted,
                    gestureRecognizers: Set()
                      ..add(
                        Factory<DragGestureRecognizer>(
                          () => VerticalDragGestureRecognizer(),
                        ),
                      ),
                  ),
                ],
              ),
            ),
          );
        }
      }
      

      试试看是否能解决你的问题

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-07
        • 2014-04-07
        • 1970-01-01
        • 1970-01-01
        • 2019-05-04
        • 1970-01-01
        • 2011-08-08
        • 1970-01-01
        相关资源
        最近更新 更多