有没有一种方法可以将下拉列表刷新添加到webview_flutter小部件?

时间:2019-07-23 20:05:12

标签: flutter webview

我正在尝试创建一个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。

1 个答案:

答案 0 :(得分:-1)

嗯,可以做到的。

  1. 在创建webView时,请将手手势识别器设置为EagerGestureRecognizer();

  2. 实现一个AllowMultipleGestureRecognizer,它扩展了VerticalDragGestureRecognizer,将rejectGesture()重写为acceptGesture();

  3. 实现RawGestureDetector,使用AllowMultipleGestureRecognizer作为“手势”;

  4. 在RawGestureDetector中放置一个LayoutBuilder(),目的是获取子上下文;

  5. 将您的webView放入LayoutBuilder。现在,webView和RawGestureDetector都可以接收手势事件。

  6. 实现翻译层,该翻译层将手势转换为滚动通知。您可能感兴趣的滚动通知是:ScrollStartNotification,OverscrollNotification,ScrollUpdateNotification和ScrollEndNotification。对于RefreshIndicator,不需要UserScrollNotification。该层可能需要一些时间才能正确执行操作;

  7. 在RawGestureDetector的回调函数中:onStart()/ onUpdte()/ onEnd(),调用转换层以生成通知。然后使用从LayoutBuilder获得的上下文来调用正在监听滚动事件的每个祖先窗口小部件。使用context.visitAncestorElements()可以实现这一点。

  8. 修改webView的平台代码(Android和iOS),以将侦听器添加到YOffset。侦听器调用“ channel”方法将偏移量传递给颤振代码。 6中的翻译层会查看YOffset以生成正确的通知(例如OverscrollNotification或ScrollUpdateNotification)。

  9. 将RawGestureDetector放入RefreshIndicator中,您就完成了!

结果: 结果是非常令人失望的。 RefreshIndicator的动画使webView重绘几次,这会导致屏幕闪烁和相当大的滞后。绝对不是良好的用户体验。 Flutter无法很好地处理繁重的“插件”小部件,应避免对WebView进行任何与动画相关的操作(例如push / pop)。

浪费时间。