Flutter使用InAppWebView时输入框聚焦后页面无法滚动问题
问题现象
- 在Android和iOS平台使用InAppWebView插件打开网页时,点击日历类输入框后,输入框会被软键盘遮挡
- 收起软键盘后,页面无法向下滚动查看完整日历内容
现有实现代码
return Stack( children: <Widget>[ progress < 1.0 ? const Center( child: CircularProgressIndicator( color: AppTheme.mainColorCircularProgressIndicator, ), ) : const SizedBox.shrink(), child: InAppWebView( initialUrlRequest: URLRequest(url: Uri.parse(widget.url)), gestureRecognizers: Set() ..add( Factory<VerticalDragGestureRecognizer>( () => VerticalDragGestureRecognizer()), ), initialOptions: InAppWebViewGroupOptions( crossPlatform: InAppWebViewOptions( useShouldOverrideUrlLoading: true, useOnDownloadStart: true, javaScriptEnabled: true, javaScriptCanOpenWindowsAutomatically: true, userAgent: _userAgentBrowser, ), android: AndroidInAppWebViewOptions( allowContentAccess: true, builtInZoomControls: true, thirdPartyCookiesEnabled: true, useHybridComposition: true, allowFileAccess: true, supportMultipleWindows: true, domStorageEnabled: true, databaseEnabled: true, ), ), shouldOverrideUrlLoading: (InAppWebViewController controller, NavigationAction navigationAction) async {}, onProgressChanged: (InAppWebViewController controller, int progress) { setState(() => this.progress = progress / 100); }, ), ), ], );
解决方案
- 调整Android端Manifest配置,给当前WebView所在的Activity添加
android:windowSoftInputMode="adjustResize"属性,确保软键盘弹出时页面布局自动重绘压缩适配高度 - 修改InAppWebView的父布局约束,不要直接放在无高度限制的Stack中,外层可嵌套
Scaffold,确认resizeToAvoidBottomInset属性为默认值true,不要手动设为false - 补充InAppWebView初始化配置,新增跨平台和双端专属滚动适配参数:
initialOptions: InAppWebViewGroupOptions( crossPlatform: InAppWebViewOptions( // 原有配置保留,新增以下配置 supportZoom: false, disableVerticalScroll: false, ), android: AndroidInAppWebViewOptions( // 原有配置保留,新增以下配置 displayZoomControls: false, ), ios: IOSInAppWebViewOptions( // 新增iOS专属配置 enableViewportScale: false, automaticallyAdjustsScrollIndicatorInsets: true, ) ),
- 新增
onPageFinished回调,注入JS代码强制网页视口适配可用高度,触发选中输入框自动滚动到可视区域:
onPageFinished: (controller, url) async { await controller.evaluateJavascript(source: """ const meta = document.createElement('meta'); meta.name = 'viewport'; meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'; document.getElementsByTagName('head')[0].appendChild(meta); window.addEventListener('resize', () => { window.scrollTo(0, document.activeElement.offsetTop); }); """); }
- 修改手势识别配置,避免自定义垂直拖拽手势和WebView自身滚动逻辑冲突,调整为:
gestureRecognizers: { Factory<VerticalDragGestureRecognizer>(() => VerticalDragGestureRecognizer()..gestureSettings = const DeviceGestureSettings(touchSlop: 8)), }
内容的提问来源于stack exchange,提问作者ameli
相关产品推荐
相关产品推荐

