【问题标题】:Flutter: How to show a CircularProgressIndicator before WebView loads the page?Flutter:如何在 WebView 加载页面之前显示 CircularProgressIndicator?
【发布时间】:2019-07-08 22:27:20
【问题描述】:

我正在使用 webview_fluttter 插件,但我找不到在 webview 显示页面之前显示 CircularProgressIndicator 的方法...

Androids WebViewClient onPageStarted/onPageFinished 相当于什么?

WebView(
  initialUrl: url,
  onWebViewCreated: (controller) {
  },
)

【问题讨论】:

标签: webview flutter


【解决方案1】:

在 0.3.5 版本中有“onPageFinished”回调。您可以使用 IndexedStack 创建 WebView 容器。

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class _WebViewContainerState extends State < WebViewContainer > {
  var _url;
  final _key = UniqueKey();
  _WebViewContainerState(this._url);
  num _stackToView = 1;

  void _handleLoad(String value) {
    setState(() {
      _stackToView = 0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: IndexedStack(
        index: _stackToView,
        children: [
          Column(
            children: < Widget > [
              Expanded(
                child: WebView(
                  key: _key,
                  javascriptMode: JavascriptMode.unrestricted,
                  initialUrl: _url,
                  onPageFinished: _handleLoad,
                )
              ),
            ],
          ),
          Container(
            color: Colors.white,
            child: Center(
              child: CircularProgressIndicator(),
            ),
          ),
        ],
      )
    );
  }
}

class WebViewContainer extends StatefulWidget {
  final url;
  WebViewContainer(this.url);
  @override
  createState() => _WebViewContainerState(this.url);
}

【讨论】:

  • 0.3.5 版本在 iOS 上运行,但在 Android 上出现此错误:注意:/Users/rlecheta/Dev/flutter/.pub-cache/hosted/pub.dartlang.org/webview_flutter -0.3.5+1/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java 使用或覆盖已弃用的 API。程序类型已存在:com.google.common.util.concurrent.ListenableFuture 在developer.android.com/studio/build/… 了解如何解决问题。
  • 升级 gradle 版本后,我的项目成功执行。但是当我尝试使用 WebView 时,我的应用程序崩溃了。就在安卓里。它适用于 iOS。您可以在此处查看完整的堆栈跟踪:livecom-chat.s3.amazonaws.com/livecomProd/…
  • 不看代码很难判断。此代码适用于我所有的 iOS/Android 设备。另外,考虑到这个插件仍然在“开发者预览”中,所以它可能是他们的错误。
  • 虽然我得到了一个严重的错误,它不断地重建自己,我的坏处,我修复了它
  • 工作得很好。谢谢。
【解决方案2】:

这对我来说工作正常

  initState() {
    isLoading = true;
  };

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: Text("Your Title",centerTitle: true
      ),
      body: Stack(
        children: <Widget>[
          new WebView(
            initialUrl: /* YourUrl*/,
            onPageFinished: (_) {
              setState(() {
                isLoading = false;
              });
            },
          ),
          isLoading ? Center( child: CircularProgressIndicator()) : Container(),
        ],
      ),
    );
  }

【讨论】:

  • "Your Title"后面不是没有)吗?
  • 我还认为您需要添加super.initState(); 才能使initState() 功能正常工作。
  • 对所有 cmets 感到抱歉,但 @override initState() 函数也是必要的。
【解决方案3】:
class _WebViewContainerState extends State<WebViewContainer> {
  var _url;
  final _key = UniqueKey();
  bool _isLoadingPage;

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

  _WebViewContainerState(this._url);

  @override
  void initState() {
    super.initState();
    _isLoadingPage = true;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          new WebView(
            key: _key,
            initialUrl: _url,
            javascriptMode: JavascriptMode.unrestricted,
            onWebViewCreated: (webViewCreate) {
              _controller.complete(webViewCreate);
            },
            onPageFinished: (finish) {
              setState(() {
                _isLoadingPage = false;
              });
            },
          ),
          _isLoadingPage
              ? Container(
                  alignment: FractionalOffset.center,
                  child: CircularProgressIndicator(),
                )
              : Container(
                  color: Colors.transparent,
                ),
        ],
      ),
    );
  }
}

【讨论】:

  • 欢迎你的兄弟。
  • 不能再与网络视图交互了!
【解决方案4】:

可选参数 hidden 和 initialChild 可用,以便您在等待页面加载时显示其他内容。如果您将 hidden 设置为 true,它将显示默认的 CircularProgressIndicator。 如果您另外指定initialChild 的小部件,您可以让它显示任何您喜欢的内容,直到页面加载。

查看此页面:flutter_webview_plugin

您可以使用initialChild指定要显示的内容

return new MaterialApp(
  title: 'Flutter WebView Demo',
  theme: new ThemeData(
    primarySwatch: Colors.blue,
  ),
  routes: {
    '/': (_) => const MyHomePage(title: 'Flutter WebView Demo'),
    '/widget': (_) => new WebviewScaffold(
      url: selectedUrl,
      appBar: new AppBar(
        title: const Text('Widget webview'),
      ),
      withZoom: true,
      withLocalStorage: true,
      hidden: true,
      initialChild: Container(
        child: const Center(
          child: CircularProgressIndicator(),
        ),
      ),
    ),
  },
);

【讨论】:

  • 您好,谢谢,我会尝试使用您的解决方案。但现在我正在使用谷歌的官方 webview 插件。我认为它缺少此功能。
  • 嗨@clipi onat,不,因为我正在使用“webview_flutter”插件。不过谢谢你的帮助。
  • 这对于任何试图在小部件树中内联渲染 webview 的人来说都不是一个好的解决方案,因为 flutter_webview_plugin 使用了覆盖层。
【解决方案5】:

我使用webview_flutterprogress_indicators的组合

这是一个示例工作代码:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';
import 'package:progress_indicators/progress_indicators.dart';




class ContactUs extends StatefulWidget {
  @override
  _ContactUsState createState() => _ContactUsState();
}

class _ContactUsState extends State<ContactUs> {

  bool vis1 = true;
  Size deviceSize;

  @override
  Widget build(BuildContext context) {

    deviceSize = MediaQuery.of(context).size;

    final lindicator = Center(
      child: AnimatedOpacity(
        // If the Widget should be visible, animate to 1.0 (fully visible). If
        // the Widget should be hidden, animate to 0.0 (invisible).
        opacity: vis1 ? 1.0 : 0.0,
        duration: Duration(milliseconds: 500),
        // The green box needs to be the child of the AnimatedOpacity
        child: HeartbeatProgressIndicator(
          child: Container(
            width: 100.0,
            height: 50.0,
            padding: EdgeInsets.fromLTRB(35.0,0.0,5.0,0.0),
            child: Row(
              children: <Widget>[
                Icon(
                  Icons.all_inclusive, color: Colors.white, size: 14.0,),
                Text(
                  "Loading View", style: TextStyle(color: Colors.white, fontSize: 6.0),),
              ],
            ),
          ),
        ),
      ),
    );

    return new Scaffold(
      appBar: new AppBar(
        title: new Row(
            children:<Widget>[
              Text('THisApp'),
              lindicator,
            ]),
        backgroundColor: Colors.red,
      ),
      body: new Container(
          child:WebView(
            initialUrl: 'https://cspydo.com.ng/',
            javaScriptMode: JavaScriptMode.unrestricted,
            onWebViewCreated: (WebViewController webViewController){
              setState(() {
                vis1=false;
              });
            },
          )
      ),
    );
  }
}

【讨论】:

  • 谢谢,但是 onWebViewCreated 一开始就被调用了……我需要知道 WebView 何时完成页面加载。我认为该插件缺少此功能。我需要的正是 Android WebViewClient 的 onPageFinished 所做的。
【解决方案6】:

找到解决方案。您可以添加initialChild并将属性隐藏设置为true。

WebviewScaffold(
hidden: true,
  url:url,initialChild: Center(
 child: Text("Plase Wait...",style: TextStyle(
  fontWeight: FontWeight.bold,
  color: Colors.deepPurpleAccent[100]
  ),)
 ) )

【讨论】:

    【解决方案7】:

    您可以使用 isLoading 并在确定数据正确加载后对其进行更改。

        class X extends StatefulWidget {
          XState createState() => XState();
        }
        class XState extends State<X>{
    
        bool isLoading = false;
    
        @override
          void initState() {
            setState(() {
              isLoading = true;
            });
            super.initState();
          }
    
        Widget build(BuildContext context) {
        return Scaffold(
              body: Column(
                  children: <Widget>[
                      isLoading ? Center(child: CircularProgressIndicator()) : WebView(...)
                  ]
                )
              );
            }
        }
    

    【讨论】:

    • 谢谢,但问题是我找不到知道 webviews 何时完成页面加载的方法..
    • 你可以使用flutter_native_web [pub.dartlang.org/packages/flutter_native_web]@rlecheta
    • 自己试过了,webview永远不会渲染。
    • 再次回到这里,我只想指出,这种逻辑毫无意义。如果 WebView 没有在树中呈现,它将如何处于加载状态?您必须在包含组件上将其不透明度或高度设置为零来隐藏它。 onPageFinished,执行交换可见性的逻辑。
    【解决方案8】:

    我在 Flutter 中使用了 A 栈。

      @override
      void initState() {
        isLoading = true;
        super.initState();
      }
    

    在构建方法中

         Stack(
            children: [
              isLoading ? Loading() : Container(),
              Container(
                child: Flex(
                  direction: Axis.vertical,
                  children: [
                    Expanded(
                      child: InAppWebView(
                        contextMenu: contextMenu,
                        initialUrl: url,
    
                        onLoadSop: (InAppWebViewController controller, url) {
                          setState(() {
                            isLoading = false;
                          });
                        },
                      )
                    ),
                  ],
                ),
              ),
            ],
          )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-18
      • 2010-12-23
      • 1970-01-01
      • 2019-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多