我正在尝试创建一个Flutter应用程序,该应用程序将在WebView内显示一个网站,并且我希望能够设置一个RefreshIndicator,当用户下拉该WebView并刷新WebView时触发该刷新指标。
我可以使用WebView,但是RefreshIndicator仅适用于垂直滚动视图。我尝试将WebView作为唯一的孩子添加到ListView,但是WebView不会下拉ListView。
我尝试将RefreshIndicator放在Webview周围,也尝试使用PageView而不是ListView
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebViewContainer extends StatefulWidget {
final url;
WebViewContainer(this.url);
@override
createState() => _WebViewContainerState(this.url);
}
class _WebViewContainerState extends State<WebViewContainer> {
final Completer<WebViewController> _controller =
Completer<WebViewController>();
var _url;
final _key = UniqueKey();
_WebViewContainerState(this._url);
// WebViewController _webViewController;
@override
Widget build(BuildContext context) {
return Scaffold(
body: RefreshIndicator(
child: ListView(children: [
Container(
child: Center(child: Text('Top')),
),
Container(
height: MediaQuery.of(context).size.height,
child: WebView(
key: _key,
initialUrl: _url,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
navigationDelegate: (navigationRequest) {
return NavigationDecision.navigate;
},
gestureRecognizers: Set()
..add(Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer())),
javascriptChannels: <JavascriptChannel>[
_toasterJavascriptChannel(context),
].toSet(),
onPageFinished: (String url) {
print('Page Finished loading: $url');
},
),
),
Container(
child: Center(child: Text('Bottom')),
),
]),
onRefresh: _refreshWebView,
),
);
}
我想要的是一种只显示Webview的方法,当他们拉下刷新的Webview时。另一个选择是,如果滚动到Webview页面的顶部,则Webview将下拉ListView。
答案 0 :(得分:-1)
嗯,可以做到的。
在创建webView时,请将手手势识别器设置为EagerGestureRecognizer();
实现一个AllowMultipleGestureRecognizer,它扩展了VerticalDragGestureRecognizer,将rejectGesture()重写为acceptGesture();
实现RawGestureDetector,使用AllowMultipleGestureRecognizer作为“手势”;
在RawGestureDetector中放置一个LayoutBuilder(),目的是获取子上下文;
将您的webView放入LayoutBuilder。现在,webView和RawGestureDetector都可以接收手势事件。
实现翻译层,该翻译层将手势转换为滚动通知。您可能感兴趣的滚动通知是:ScrollStartNotification,OverscrollNotification,ScrollUpdateNotification和ScrollEndNotification。对于RefreshIndicator,不需要UserScrollNotification。该层可能需要一些时间才能正确执行操作;
在RawGestureDetector的回调函数中:onStart()/ onUpdte()/ onEnd(),调用转换层以生成通知。然后使用从LayoutBuilder获得的上下文来调用正在监听滚动事件的每个祖先窗口小部件。使用context.visitAncestorElements()可以实现这一点。
修改webView的平台代码(Android和iOS),以将侦听器添加到YOffset。侦听器调用“ channel”方法将偏移量传递给颤振代码。 6中的翻译层会查看YOffset以生成正确的通知(例如OverscrollNotification或ScrollUpdateNotification)。
将RawGestureDetector放入RefreshIndicator中,您就完成了!
结果: 结果是非常令人失望的。 RefreshIndicator的动画使webView重绘几次,这会导致屏幕闪烁和相当大的滞后。绝对不是良好的用户体验。 Flutter无法很好地处理繁重的“插件”小部件,应避免对WebView进行任何与动画相关的操作(例如push / pop)。
浪费时间。