extended_sliver
extended_sliver copied to clipboard
SliverToNestedScrollBoxAdapter, webview disappear on keyboard input open
I'm using part of the code from the example https://github.com/fluttercandies/extended_sliver/blob/master/example/lib/pages/nested/webview.dart
When I click on an editable field of the Webview, the complet view disappear, do you know why ?
import 'dart:io';
import 'dart:ui';
import 'package:extended_sliver/extended_sliver.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class NestedWebview extends StatelessWidget {
NestedWebview({
required this.url,
Key? key,
}) : nestedWebviewController = NestedWebviewController(url),
super(key: key);
final String url;
final NestedWebviewController nestedWebviewController;
final ScrollController scrollController = ScrollController();
@override
Widget build(BuildContext context) {
return CustomScrollView(
primary: false,
shrinkWrap: true,
controller: scrollController,
slivers: <Widget>[
ValueListenableBuilder<double>(
valueListenable: nestedWebviewController.scrollHeightNotifier,
builder: (
BuildContext context,
double scrollHeight,
Widget? child,
) {
return SliverToNestedScrollBoxAdapter(
childExtent: scrollHeight,
onScrollOffsetChanged: (double scrollOffset) {
double y = scrollOffset;
if (Platform.isAndroid) {
// https://github.com/flutter/flutter/issues/75841
y *= window.devicePixelRatio;
}
nestedWebviewController.webviewController
?.scrollTo(0, y.ceil());
},
child: child,
);
},
child: WebView(
initialUrl: nestedWebviewController.initialUrl,
onPageStarted: nestedWebviewController.onPageStarted,
onPageFinished: nestedWebviewController.onPageFinished,
onWebResourceError: nestedWebviewController.onWebResourceError,
onWebViewCreated: nestedWebviewController.onWebViewCreated,
javascriptChannels: <JavascriptChannel>{
nestedWebviewController.scrollHeightNotifierJavascriptChannel
},
javascriptMode: JavascriptMode.unrestricted,
),
),
],
);
}
}
class NestedWebviewController {
NestedWebviewController(this.initialUrl);
final String initialUrl;
WebViewController? _webviewController;
WebViewController? get webviewController => _webviewController;
ValueNotifier<double> scrollHeightNotifier = ValueNotifier<double>(1);
ValueNotifier<WebViewStatus> webViewStatusNotifier =
ValueNotifier<WebViewStatus>(WebViewStatus.loading);
void onWebViewCreated(WebViewController controller) {
_webviewController = controller;
}
void onPageStarted(String url) {
if (url == initialUrl ||
webViewStatusNotifier.value == WebViewStatus.failed) {
webViewStatusNotifier.value = WebViewStatus.loading;
}
}
void onPageFinished(String url) {
if (webViewStatusNotifier.value != WebViewStatus.failed) {
_webviewController?.runJavascript(scrollHeightJs);
}
}
void onWebResourceError(WebResourceError error) {
webViewStatusNotifier.value = WebViewStatus.failed;
}
JavascriptChannel get scrollHeightNotifierJavascriptChannel =>
JavascriptChannel(
name: 'ScrollHeightNotifier',
onMessageReceived: (JavascriptMessage message) {
final String msg = message.message;
final double? height = double.tryParse(msg);
if (height != null) {
scrollHeightNotifier.value = height;
webViewStatusNotifier.value = WebViewStatus.completed;
}
},
);
}
enum WebViewStatus {
loading,
failed,
completed,
}
const String scrollHeightJs = '''(function() {
var height = 0;
var notifier = window.ScrollHeightNotifier || window.webkit.messageHandlers.ScrollHeightNotifier;
if (!notifier) return;
function checkAndNotify() {
var curr = document.body.scrollHeight;
if (curr !== height) {
height = curr;
notifier.postMessage(height.toString());
}
}
var timer;
var ob;
if (window.ResizeObserver) {
ob = new ResizeObserver(checkAndNotify);
ob.observe(document.body);
} else {
timer = setTimeout(checkAndNotify, 200);
}
window.onbeforeunload = function() {
ob && ob.disconnect();
timer && clearTimeout(timer);
};
})();''';
shrinkWrap: true, why need this
shrinkWrap: true, why need this
You are right this is not useful, I removed it.
I added resizeToAvoidBottomInset: false,
to the parent Scaffold()
is not totally working but it better. There is still some weird views:
Scaffold(
resizeToAvoidBottomInset: false,
body: NestedScrollView (
....
body: NestedWebview(
url: 'https://www.qwant.com',
);
)
runnable,simple demo,plz