如何为每个页面加载颤动在 Web 视图中实现进度指示器?

Posted

技术标签:

【中文标题】如何为每个页面加载颤动在 Web 视图中实现进度指示器?【英文标题】:How to implement progress Indicator in web view for every page load flutter? 【发布时间】:2021-04-24 13:05:56 【问题描述】:

我目前正在使用此代码在 webview 加载之前显示进度指示器:

我的完整 main.dart 代码:

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
//import 'package:mtcl/utils/AppColors.dart';
import 'package:custom_splash/custom_splash.dart';
import 'package:connectivity/connectivity.dart';

void main() 
  //runApp(MyApp());

  //var result = Connectivity().checkConnectivity();

  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());

  // if (result == ConnectivityResult.none) 
  //   WidgetsFlutterBinding.ensureInitialized();
  //   runApp(MyApp());
  //  else if (result == ConnectivityResult.mobile) 
  //   WidgetsFlutterBinding.ensureInitialized();
  //   runApp(MyApp());
  //  else if (result == ConnectivityResult.wifi) 
  //   WidgetsFlutterBinding.ensureInitialized();
  //   runApp(MyApp());
  // 


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
        title: "MTCL Client",
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primarySwatch: Colors.red,
        ),
        home: Scaffold(body: splash()));
  


class splash extends StatefulWidget 
  @override
  _splashState createState() => _splashState();


class _splashState extends State<splash> 
  @override
  Widget build(BuildContext context) 
    return CustomSplash(
      backGroundColor: Color(0xFFFF9800),
      imagePath: "assets/images/logo.png",
      home: WebViewClass(),
      duration: 10,
      animationEffect: "zoom-in",
    );
  


class WebViewClass extends StatefulWidget 
  WebViewState createState() => WebViewState();


class WebViewState extends State<WebViewClass> 
  num position = 1;

  final key = UniqueKey();

  doneLoading(String A) 
    setState(() 
      position = 0;
    );
  

  startLoading(String A) 
    setState(() 
      position = 1;
    );
  

  //Check Internet Code Starts

  //Check Internet Code Ended here
  @override
  Widget build(BuildContext context) 
    return Scaffold(
        //appBar: AppBar(title: Text('Show ProgressBar While Loading Webview')),
        appBar: PreferredSize(
          child: Container(),
          preferredSize: Size.fromHeight(0.0),
        ),
        body: IndexedStack(index: position, children: <Widget>[
          WebView(
            initialUrl: 'http://110.38.4.4/login/client',
            javascriptMode: JavascriptMode.unrestricted,
            key: key,
            onPageFinished: doneLoading,
            onPageStarted: startLoading,
          ),
          Container(
            color: Colors.white,
            child: Center(
                child: CircularProgressIndicator(
              valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),
            )),
          ),
        ]));
  

现在我需要为每个操作立即显示进度指示器,例如如果用户在填写登录凭据后单击登录按钮,我希望在单击按钮后立即显示进度指示器,而现在进度指示器正在显示单击按钮片刻后。我怎样才能在颤振中实现这样的事情?

【问题讨论】:

你找到解决方案了吗? 【参考方案1】:

您可以在navigationDelegate 中添加触发进度指示器的代码:

WebView(
  initialUrl: 'https://flutter.dev',
  navigationDelegate: (NavigationRequest request) 
    print('Navigating to $request.url');
    // Call any code here that you want
    return NavigationDecision.navigate;
  ,
),

【讨论】:

此解决方案适用于所提出的问题。每次启动导航时,都会触发委托。如果你在那个时候显示你的进度指示器,它就会起作用。 已经可以使用了。让我发布我的完整工作代码【参考方案2】:

根据 Soares 建议的 navigationDelegate,这是我的完整工作代码

class _WikipediaExplorerState extends State<WikipediaExplorer> 
  Completer<WebViewController> _controller = Completer<WebViewController>();
  final Set<String> _favorites = Set<String>();

  String title, url;
  bool isLoading = true;
  final _key = UniqueKey();

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: const Text('Facebook Test Webview'),
        // This drop down menu demonstrates that Flutter widgets can be shown over the web view.
        actions: <Widget>[
          NavigationControls(_controller.future),
          Menu(_controller.future, () => _favorites),
        ],
      ),
      body: Builder(builder: (BuildContext context) 
        return Stack(
          children: <Widget>[
            WebView(
              initialUrl: 'https://www.facebook.com/',
              javascriptMode: JavascriptMode.unrestricted,
              onWebViewCreated: (WebViewController webViewController) 
                _controller.complete(webViewController);
              ,
              // TODO(iskakaushik): Remove this when collection literals makes it to stable.
              // ignore: prefer_collection_literals
              javascriptChannels: <JavascriptChannel>[
                _toasterJavascriptChannel(context),
              ].toSet(),
              navigationDelegate: (NavigationRequest request) 
                if (request.url.startsWith('https://www.youtube.com/')) 
                  print('blocking navigation to $request');
                  return NavigationDecision.prevent;
                
                print('allowing navigation to $request');
                setState(() 
                  isLoading = true;
                );
                return NavigationDecision.navigate;
              ,
              onPageFinished: (String url) 
                print('Page finished loading: $url');
                setState(() 
                  isLoading = false;
                );
              ,
            ),
            isLoading
                ? Center(
                    child: CircularProgressIndicator(),
                  )
                : Stack(),
          ],
        );
      ),
    );

  

每次在应用内点击新链接时,都会启动一个循环进度对话框

【讨论】:

以上是关于如何为每个页面加载颤动在 Web 视图中实现进度指示器?的主要内容,如果未能解决你的问题,请参考以下文章

如何为单独的 TextView 设置单独的进度条

如何为每个网格项目显示不同的名称和不同的登录页面?

如何为 iOS 强制颤动设备方向

VUE项目实战61添加页面加载进度条效果

VUE项目实战61添加页面加载进度条效果

NuxtJS - 我想知道如何为特定页面实现加载