我正在尝试创建一个 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,
),
);
}
Run Code Online (Sandbox Code Playgroud)
我想要的是一种只显示 Webview 的方法,当他们下拉它刷新的 Webview 时。另一种选择是,如果您滚动到 Webview 中的页面顶部,Webview 是否会下拉 ListView。
小智 0
嗯,这是可以做到的。
创建webView时,将gestureRecognizers设置为EagerGestureRecognizer();
实现一个AllowMultipleGestureRecognizer,它扩展了VerticalDragGestureRecognizer,将rejectGesture()覆盖为acceptGesture();
实现一个RawGestureDetector,使用AllowMultipleGestureRecognizer作为“手势”;
在RawGestureDetector中放一个LayoutBuilder(),目的是获取子上下文;
将您的 webView 放入 LayoutBuilder 中。现在,webView 和 RawGestureDetector 都可以接收手势事件。
实现一个翻译层,将手势翻译成滚动通知。您可能感兴趣的滚动通知是:ScrollStartNotification、OverscrollNotification、ScrollUpdateNotification 和 ScrollEndNotification。UserScrollNotification 对于 RefreshIndicator 来说不是必需的。这一层可能需要一些时间才能把事情做好;
在RawGestureDetector的回调函数:onStart()/onUpdte()/onEnd()中,调用翻译层来生成通知。然后使用从 LayoutBuilder 获取的上下文来调用正在侦听滚动事件的每个祖先小部件。使用 context.visitAncestorElements() 来实现这一点。
修改 webView 的平台代码(Android 和 iOS),以向 YOffset 添加侦听器。侦听器调用“channel”方法将偏移量传递给您的 flutter 代码。6 中的转换层查看 YOffset 以生成正确的通知(例如 OverscrollNotification 或 ScrollUpdateNotification)。
将 RawGestureDetector 放入 RefreshIndicator 中,就完成了!
结果:结果相当令人失望。RefreshIndicator 的动画会导致 webView 重绘几次,从而导致屏幕闪烁和相当大的延迟。这绝对不是一个好的用户体验。Flutter 无法很好地处理重型“插件”小部件,应避免对 webView 进行任何与动画相关的操作(例如推送/弹出)。
时间浪费了。
| 归档时间: |
|
| 查看次数: |
2221 次 |
| 最近记录: |