eyflutter_webview 2.0.9 copy "eyflutter_webview: ^2.0.9" to clipboard
eyflutter_webview: ^2.0.9 copied to clipboard

eyflutter_webview

example/lib/main.dart

// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ignore_for_file: public_member_api_docs

import 'dart:async';
import 'dart:io';

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

void main() => runApp(MaterialApp(home: WebViewExample()));

const String kNavigationExamplePage = r'''
<!DOCTYPE html><html>
<head><title>Navigation Delegate Example</title></head>
<body>
<p>&nbsp; &nbsp; &nbsp; &nbsp;圆周率符号π。1965年,英国数学家约翰·沃利斯(JohnWallis)出版了一本数学专著,其中他推导出一个公式,发现圆周率等于无穷个分数相乘的积。不难发现它是有规律可寻的,那么我们常说的圆周率前100位又是如何去记得呢以及有关圆周率的那些趣事。下面小编就带大家讲讲一起来说说。</p><p>一、<b>圆周率前100位怎么背</b></p><p>1、3.14159山巅一寺一壶酒,26尔乐,535苦煞吾,897把酒吃,932酒杀尔,384杀不死,626乐啊乐,43四三,38327三爸三尔妻,9(还有一壶)酒。</p><p>2、5028841吾领儿爬怕撕腰,9716939舅妻一楼救三舅,9375105鸠山骑虎要领虎,8209749爸爱零酒骑士酒,4459230试试五舅爱山岭,7816406妻怕要肉是零肉。</p><p>3、2862089二爸搂儿领八舅,9802803是怕二虎扇四儿,4825342就怕六儿怕领伞,1170679咬咬气铃漏汽酒。</p><blockquote><ul><li><b>连起来就是:</b><br/>3.14159&nbsp; 26&nbsp; 535&nbsp; 897&nbsp; 932&nbsp; 384&nbsp; 626&nbsp; 43&nbsp; 38327&nbsp; 9&nbsp; 5028841&nbsp; 9716939&nbsp; 9375105&nbsp; 8209749&nbsp; 4459230&nbsp; 7816406&nbsp; 2862089&nbsp; 9802803&nbsp; 4825342&nbsp; 1170679<br/>山巅一寺一壶酒 尔乐 苦煞吾 把酒吃 酒杀尔 杀不死 乐啊乐 四三 三爸三尔妻 (还有一壶)酒 吾领儿爬怕撕腰 舅妻一楼救三舅 鸠山骑虎要领虎 爸爱零酒骑士酒 试试五舅爱山岭 妻怕要肉是零肉 二爸搂儿领八舅 二爸搂儿领八舅 就怕六儿怕领伞 咬咬气铃漏汽酒<br/></li></ul></blockquote><p>二、<b>圆周率趣闻事件</b></p><p>1、历史上最马拉松式的人手π值计算,其一是德国的鲁道夫·范·科伊伦(Ludolph van Ceulen),他几乎耗尽了一生的时间,于1609年得到了圆周率的35位精度值,以至于圆周率在德国被称为Ludolphine number;其二是英国的威廉·山克斯(William Shanks),他耗费了15年的光阴,在1874年算出了圆周率的小数点后707位,并将其刻在了墓碑上作为一生的荣誉。可惜,后人发现,他从第528位开始就算错了。<br/></p><p>2、在谷歌公司2005年的一次公开募股中,共集资四十多亿美元,A股发行数量是14,159,265股,这当然是由π小数点后的位数得来。(顺便一提,谷歌公司2004年的首次公开募股,集资额为$2,718,281,828,与数学常数e有关)</p><p>3、排版软件TeX从第三版之后的版本号为逐次增加一位小数,使之越来越接近π的值:3.1,3.14,……当前的最新版本号是3.1415926。</p><p>4、每年3月14日为圆周率日,“终极圆周率日”则是1592年3月14日6时54分,(因为其英式记法为“3/14/15926.54”,恰好是圆周率的十位近似值。)和3141年5月9日2时6分5秒(从前往后,3.14159265)</p><p>5、7月22日为圆周率近似日(英国式日期记作22/7,看成圆周率的近似分数)</p><p>本文到此结束,希望对大家有所帮助。</p>
</body>
</html>
''';

class WebViewExample extends StatefulWidget {
  @override
  _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  final Completer<WebViewController> _controller = Completer<WebViewController>();

  @override
  void initState() {
    super.initState();
    if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter WebView example'),
        // This drop down menu demonstrates that Flutter widgets can be shown over the web view.
        actions: <Widget>[
          NavigationControls(_controller.future),
          SampleMenu(_controller.future),
        ],
      ),
      // We're using a Builder here so we have a context that is below the Scaffold
      // to allow calling Scaffold.of(context) so we can show a snackbar.
      body: Builder(builder: (BuildContext context) {
        return WebView(
          // initialUrl: 'https://flutter.dev',
          htmlData: kNavigationExamplePage,
          javascriptMode: JavascriptMode.unrestricted,
          onWebViewCreated: (WebViewController webViewController) {
            _controller.complete(webViewController);
          },
          onProgress: (int progress) {
            print("WebView is loading (progress : $progress%)");
          },
          javascriptChannels: <JavascriptChannel>{
            _toasterJavascriptChannel(context),
          },
          navigationDelegate: (NavigationRequest request) {
            if (request.url.startsWith('https://www.youtube.com/')) {
              print('blocking navigation to $request}');
              return NavigationDecision.prevent;
            }
            print('allowing navigation to $request');
            return NavigationDecision.navigate;
          },
          onPageStarted: (String url) {
            print('Page started loading: $url');
          },
          onPageFinished: (String url) {
            print('Page finished loading: $url');
          },
          gestureNavigationEnabled: true,
        );
      }),
      floatingActionButton: favoriteButton(),
    );
  }

  JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
    return JavascriptChannel(
        name: 'Toaster',
        onMessageReceived: (JavascriptMessage message) {
          // ignore: deprecated_member_use
          // Scaffold.of(context).showSnackBar(
          //   SnackBar(content: Text(message.message)),
          // );
        });
  }

  Widget favoriteButton() {
    return FutureBuilder<WebViewController>(
        future: _controller.future,
        builder: (BuildContext context, AsyncSnapshot<WebViewController> controller) {
          if (controller.hasData) {
            return FloatingActionButton(
              onPressed: () async {
                // final String url = (await controller.data!.currentUrl())!;
                // ignore: deprecated_member_use
                // Scaffold.of(context).showSnackBar(
                //   SnackBar(content: Text('Favorited $url')),
                // );
              },
              child: const Icon(Icons.favorite),
            );
          }
          return Container();
        });
  }
}

enum MenuOptions {
  showUserAgent,
  listCookies,
  clearCookies,
  addToCache,
  listCache,
  clearCache,
  navigationDelegate,
}

class SampleMenu extends StatelessWidget {
  SampleMenu(this.controller);

  final Future<WebViewController> controller;
  final CookieManager cookieManager = CookieManager();

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<WebViewController>(
      future: controller,
      builder: (BuildContext context, AsyncSnapshot<WebViewController> controller) {
        return PopupMenuButton<MenuOptions>(
          onSelected: (MenuOptions value) {
            switch (value) {
              case MenuOptions.showUserAgent:
                _onShowUserAgent(controller.data!, context);
                break;
              case MenuOptions.listCookies:
                _onListCookies(controller.data!, context);
                break;
              case MenuOptions.clearCookies:
                _onClearCookies(context);
                break;
              case MenuOptions.addToCache:
                _onAddToCache(controller.data!, context);
                break;
              case MenuOptions.listCache:
                _onListCache(controller.data!, context);
                break;
              case MenuOptions.clearCache:
                _onClearCache(controller.data!, context);
                break;
              case MenuOptions.navigationDelegate:
                _onNavigationDelegateExample(controller.data!, context);
                break;
            }
          },
          itemBuilder: (BuildContext context) => <PopupMenuItem<MenuOptions>>[
            PopupMenuItem<MenuOptions>(
              value: MenuOptions.showUserAgent,
              child: const Text('Show user agent'),
              enabled: controller.hasData,
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.listCookies,
              child: Text('List cookies'),
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.clearCookies,
              child: Text('Clear cookies'),
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.addToCache,
              child: Text('Add to cache'),
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.listCache,
              child: Text('List cache'),
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.clearCache,
              child: Text('Clear cache'),
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.navigationDelegate,
              child: Text('Navigation Delegate example'),
            ),
          ],
        );
      },
    );
  }

  void _onShowUserAgent(WebViewController controller, BuildContext context) async {
    // Send a message with the user agent string to the Toaster JavaScript channel we registered
    // with the WebView.
    await controller.evaluateJavascript('Toaster.postMessage("User Agent: " + navigator.userAgent);');
  }

  void _onListCookies(WebViewController controller, BuildContext context) async {
    // final String cookies =
    //     await controller.evaluateJavascript('document.cookie');
    // ignore: deprecated_member_use
    // Scaffold.of(context).showSnackBar(SnackBar(
    //   content: Column(
    //     mainAxisAlignment: MainAxisAlignment.end,
    //     mainAxisSize: MainAxisSize.min,
    //     children: <Widget>[
    //       const Text('Cookies:'),
    //       _getCookieList(cookies),
    //     ],
    //   ),
    // ));
  }

  void _onAddToCache(WebViewController controller, BuildContext context) async {
    await controller
        .evaluateJavascript('caches.open("test_caches_entry"); localStorage["test_localStorage"] = "dummy_entry";');
    // ignore: deprecated_member_use
    // Scaffold.of(context).showSnackBar(const SnackBar(
    //   content: Text('Added a test entry to cache.'),
    // ));
  }

  void _onListCache(WebViewController controller, BuildContext context) async {
    await controller.evaluateJavascript('caches.keys()'
        '.then((cacheKeys) => JSON.stringify({"cacheKeys" : cacheKeys, "localStorage" : localStorage}))'
        '.then((caches) => Toaster.postMessage(caches))');
  }

  void _onClearCache(WebViewController controller, BuildContext context) async {
    await controller.clearCache();
    // ignore: deprecated_member_use
    // Scaffold.of(context).showSnackBar(const SnackBar(
    //   content: Text("Cache cleared."),
    // ));
  }

  void _onClearCookies(BuildContext context) async {
    // final bool hadCookies = await cookieManager.clearCookies();
    // String message = 'There were cookies. Now, they are gone!';
    // if (!hadCookies) {
    //   message = 'There are no cookies.';
    // }
    // ignore: deprecated_member_use
    // Scaffold.of(context).showSnackBar(SnackBar(
    //   content: Text(message),
    // ));
  }

  void _onNavigationDelegateExample(WebViewController controller, BuildContext context) async {
    // final String contentBase64 = base64Encode(const Utf8Encoder().convert(kNavigationExamplePage));
    // await controller.loadUrl('data:text/html;base64,$contentBase64');
    controller.loadData(kNavigationExamplePage);
  }

// Widget _getCookieList(String cookies) {
//   if (cookies == '""') {
//     return Container();
//   }
//   final List<String> cookieList = cookies.split(';');
//   final Iterable<Text> cookieWidgets =
//       cookieList.map((String cookie) => Text(cookie));
//   return Column(
//     mainAxisAlignment: MainAxisAlignment.end,
//     mainAxisSize: MainAxisSize.min,
//     children: cookieWidgets.toList(),
//   );
// }
}

class NavigationControls extends StatelessWidget {
  const NavigationControls(this._webViewControllerFuture);

  final Future<WebViewController> _webViewControllerFuture;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<WebViewController>(
      future: _webViewControllerFuture,
      builder: (BuildContext context, AsyncSnapshot<WebViewController> snapshot) {
        final bool webViewReady = snapshot.connectionState == ConnectionState.done;
        WebViewController? controller = snapshot.data;
        return Row(
          children: <Widget>[
            IconButton(
              icon: const Icon(Icons.arrow_back_ios),
              onPressed: !webViewReady
                  ? null
                  : () async {
                      if ((await controller?.canGoBack()) ?? false) {
                        await controller?.goBack();
                      } else {
                        // ignore: deprecated_member_use
                        // Scaffold.of(context).showSnackBar(
                        //   const SnackBar(content: Text("No back history item")),
                        // );
                        return;
                      }
                    },
            ),
            IconButton(
              icon: const Icon(Icons.arrow_forward_ios),
              onPressed: !webViewReady
                  ? null
                  : () async {
                      if ((await controller?.canGoForward()) ?? false) {
                        await controller?.goForward();
                      } else {
                        // ignore: deprecated_member_use
                        // Scaffold.of(context).showSnackBar(
                        //   const SnackBar(
                        //       content: Text("No forward history item")),
                        // );
                        return;
                      }
                    },
            ),
            IconButton(
              icon: const Icon(Icons.replay),
              onPressed: !webViewReady
                  ? null
                  : () {
                      controller?.reload();
                    },
            ),
          ],
        );
      },
    );
  }
}