I showModalBottomSheet with Webview show url https://www.youtube.com it can't scroll when it show, must wait moment then can scroll, if I add any characters in the end of web, it can scroll anytime, or I don't set the inset, make the webview's width equal to the screen, it always can scroll anytime, I try use webview_flutter or flutter_inappwebview, have the same problem,
The device is iPhone 12 iOS 16.1。
the code
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// ignore_for_file: public_member_api_docs
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter/material.dart';
import 'package:web_test/widget_show_card_rule.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() => runApp(const MaterialApp(home: WebViewExample()));
class WebViewExample extends StatefulWidget {
const WebViewExample({super.key});
@override
State<WebViewExample> createState() => _WebViewExampleState();
}
class _WebViewExampleState extends State<WebViewExample> {
late final WebViewController _controller;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.green,
appBar: AppBar(
title: const Text('Flutter WebView example'),
),
body: Container(
height: 300,
padding: const EdgeInsets.only(left: 15, right: 15),
child: InAppWebView(
initialUrlRequest: URLRequest(
url: Uri.parse(
'https://www.youtube.com')),
),
),
floatingActionButton: favoriteButton(),
);
}
Widget favoriteButton() {
return FloatingActionButton(
onPressed: () async {
_checkRule();
},
child: const Icon(Icons.favorite),
);
}
_checkRule() {
showModalBottomSheet(
enableDrag: false,
isScrollControlled: true,
context: context,
backgroundColor: Colors.transparent,
builder: (context) {
return const ShowCardRule();
});
}
}
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_android/webview_flutter_android.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
class ShowCardRule extends StatefulWidget {
const ShowCardRule({super.key});
@override
ShowCardRuleState createState() => ShowCardRuleState();
}
class ShowCardRuleState extends State<ShowCardRule> {
late final WebViewController _controller;
final Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers = {
Factory(() => EagerGestureRecognizer())
};
UniqueKey _key = UniqueKey();
@override
void initState() {
super.initState();
// #docregion platform_features
late final PlatformWebViewControllerCreationParams params;
if (WebViewPlatform.instance is WebKitWebViewPlatform) {
params = WebKitWebViewControllerCreationParams(
allowsInlineMediaPlayback: true,
mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{},
);
} else {
params = const PlatformWebViewControllerCreationParams();
}
final WebViewController controller =
WebViewController.fromPlatformCreationParams(params);
// #enddocregion platform_features
controller
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
debugPrint('WebView is loading (progress : $progress%)');
},
onPageStarted: (String url) {
debugPrint('Page started loading: $url');
},
onPageFinished: (String url) {
debugPrint('Page finished loading: $url');
},
onWebResourceError: (WebResourceError error) {
debugPrint('''
Page resource error:
code: ${error.errorCode}
description: ${error.description}
errorType: ${error.errorType}
isForMainFrame: ${error.isForMainFrame}
''');
},
onNavigationRequest: (NavigationRequest request) {
if (request.url.startsWith('https://www.youtube.com/')) {
debugPrint('blocking navigation to ${request.url}');
return NavigationDecision.prevent;
}
debugPrint('allowing navigation to ${request.url}');
return NavigationDecision.navigate;
},
onUrlChange: (UrlChange change) {
debugPrint('url change to ${change.url}');
},
),
)
..addJavaScriptChannel(
'Toaster',
onMessageReceived: (JavaScriptMessage message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
},
)
..loadRequest(Uri.parse('https://www.youtube.com'));
// #docregion platform_features
if (controller.platform is AndroidWebViewController) {
AndroidWebViewController.enableDebugging(true);
(controller.platform as AndroidWebViewController)
.setMediaPlaybackRequiresUserGesture(false);
}
// #enddocregion platform_features
_controller = controller;
}
@override
Widget build(BuildContext context) {
double webHeight = 400;
double contentTop = 24;
double titleHeight = 25;
double topBlankHeight = MediaQuery.of(context).size.height - webHeight - titleHeight - contentTop;
return Align(
alignment: Alignment.topCenter,
child: Column(children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Container(height: topBlankHeight, color: Colors.transparent),
),
Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.vertical(top: Radius.circular(8)),
color: Colors.white,
),
padding: EdgeInsets.only(top: contentTop, left: 18, right: 18),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
height: titleHeight,
child: Row(
children: [
Text('使用须知',
style: TextStyle(
color: HexColor('#333333'),
fontSize: 18,
fontWeight: FontWeight.w600)),
Expanded(child: SizedBox()),
Container(
alignment: Alignment.centerRight,
width: 60,
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
),
)
],
)),
Container(
height: webHeight,
padding: EdgeInsets.only(top: 15),
child: WebViewWidget(key: _key,controller: _controller, gestureRecognizers: gestureRecognizers,))
],
),
)
]),
);
}
}
I took a look at your problem, and the reason of the scroll not working initially is because of the loading time of your images on the webview.
Even if the callback onPageFinished is triggered, it doesn't appear to load all the images, and that's why you can view most of the text in the webview, but not images, thus you can't scroll much.
The problem does not actually come from the webview_flutter or inappwebview plugin, but from the web page itself. If you can manage to trigger some action once all images have loaded, you'll be able, by sending a message from your webpage to the flutter webview controller, to make the user know that images are loading.
I used a combination of this post https://stackoverflow.com/a/11071687/14227800 ; the use of a Completer called imageLoadCompleter, and the onConsoleMessage callback from the webview, to : (0). Define the imageLoad completer.
Here is the "ShowCardRule" widget updated with the loader :
I did put comments with the proper tag to explain this.
Hope this helps