Flutter - 在webview上实现下拉刷新?

3

你好,我想问一下在Flutter中是否可以重新加载WebView?我搜索了一下,大部分都使用FAB(浮动操作按钮)来重新加载网站,但对于WebViews来说很少。是否有任何方法在WebView屏幕上实现它?

到目前为止,我尝试过SwipeDetector包Pull-to-refresh包,但两者都不起作用,下拉刷新几乎能够实现,但会完全关闭我的应用程序(我已经遵循了文档,但似乎仅适用于ListViews)。

以下是我的代码:

class _HomePageState extends State<HomePage> {
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
  WebViewController myController;
  final flutterWebviewPlugin = new WebView();

  _exitApp(BuildContext context, Future<WebViewController> controller) async {
    controller.then((data) async {
      WebViewController controller = data;
      var goBack = await controller.canGoBack();
      if (goBack == true) {
        print("onwill go back");
        controller.goBack();
      } else {
        print("onwill not go back");
        Navigator.pop(context);
      }
    });
  }

  @override
  void initState() {
    super.initState();
    firebaseCloudMessagingListeners();
  }

  void firebaseCloudMessagingListeners() {
    if (Platform.isIOS) iOSPermission();

    _firebaseMessaging.getToken().then((token) {
      print(token);
    });

    _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        setState(() {
          print("${message['data']['url']}");
          Navigator.push(
              context,
              MaterialPageRoute(
                  builder: (BuildContext context) => NotificationClicked()));
        });
      },
      onResume: (Map<String, dynamic> message) async {
        print("${message['data']['url']}");
      },
      onLaunch: (Map<String, dynamic> message) async {
        print("${message['data']['url']}");
      },
    );
  }

  void iOSPermission() {
    _firebaseMessaging.requestNotificationPermissions(
        IosNotificationSettings(sound: true, badge: true, alert: true));
    _firebaseMessaging.onIosSettingsRegistered
        .listen((IosNotificationSettings settings) {
      print("Settings registered: $settings");
    });
  }

  Completer<WebViewController> _controller = Completer<WebViewController>();


  @override
  Widget build(BuildContext context) {
    return WillPopScope(
        onWillPop: () => _exitApp(context, _controller.future),
        child: SafeArea(
    child: Scaffold(
      body: WebView(
          initialUrl: 'https://syncshop.online/en/',
          javascriptMode: JavascriptMode.unrestricted,
          onWebViewCreated: (controller) {
            _controller.complete(controller);
          },
          onPageFinished: (controller) async {
            (await _controller.future).evaluateJavascript(
        "document.getElementsByClassName('footer-container')[0].style.display='none';");
            (await _controller.future).evaluateJavascript(
        "document.getElementById('st_notification_1').style.display='none';");
            (await _controller.future).evaluateJavascript(
        "document.getElementById('sidebar_box').style.display='none';");
          },
        ),
      floatingActionButton: FutureBuilder<WebViewController>(
        future: _controller.future,
        builder: (BuildContext context,
            AsyncSnapshot<WebViewController> controller) {
          if (controller.hasData) {
            return FloatingActionButton(
              onPressed: () {
                controller.data.reload();
              },
              child: Icon(Icons.refresh),
            );
          }
          return Container();
        },
      ),
    ),
        ),
      );
  }
}

我很愿意帮助你,但我的Android模拟器在同一棵树中使用PullToRefresh和WebView部件时会崩溃。 - J. S.
1
嘿,这可能是你们需要的KDC和@JoãoSoares。 https://dev59.com/YLXna4cB1Zd3GeqPS--M - leemuljadi
@leemuljadi 我想我会再试一次。如果我没记错的话,上次我尝试过了,但是我不确定在 onSwipe: () {} 中应该放什么,因为答案使用的是来自不同插件的 WebviewScaffold,而不仅仅是我正在使用的 WebView()(来自 Flutter 团队)。 - KDC
1个回答

0

也许你可以尝试使用RefreshIndicator,我个人没有在WebView中尝试过,但希望它能够正常工作。

return Scaffold(
  body: RefreshIndicator(
    onRefresh: () => _controller.reload(),
    child: Webview(),
  ),
),

嗨,刚看到你的回答。我想问一下,如果使用不同的名称来命名void函数是否可以?因为我已经声明了initState。我也更新了我的代码。 - KDC
同时,```_setupFeed() async { await controller.data.reload(); setState(() { WebView(); }); }会报错,提示控制器未定义。 - KDC
嗨,基本上上面的代码只是展示了它如何工作的想法,然后你需要根据你的条件修改上面的代码,正如我之前提到的,我从未将其用于WebView。所以 _setupFeed() 方法的想法是当你向下拖动屏幕时,它会触发该方法,从而刷新页面。也许可以使用从网络检索数据的方法来替换 await controller.data.reload()。将 _setupFeed(); 放在 initState 中的想法是在小部件第一次构建时调用它,因此你只需将其放在 initState 方法中即可。 - leemuljadi
也许可以忽略initState和_setupFeed(),尝试使用以下代码替代: return Scaffold( body: RefreshIndicator( onRefresh: () => _controller.reload(), child: Webview(), ), ), - leemuljadi
嗨,我已经尝试并修改了你说的内容,但我认为这是webview的限制,但我仍然会寻找解决方案。谢谢。 - KDC
你可以尝试他在这里所做的事情: https://dev59.com/PbXna4cB1Zd3GeqPJFUu 然后使用RefreshIndicator()来实现它。希望这能帮到你。 - leemuljadi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接