Flutter之WebView

作者: h2coder | 来源:发表于2023-07-18 14:17 被阅读0次

    前言

    • Flutter应用嵌入WebView,实际是将原生平台的WebView嵌入到Flutter的视图中,官方有推出封装插件webview_flutter,但功能偏少,就连安卓平台上响应H5的文件选择input标签都没有处理,这个问题在原生应用也是有的,需要开发者自己解决的,那么如果基于官方的webview_flutter插件去修改的话,太麻烦了

    • 所以,我使用的是另外一个第三方插件flutter_inappwebview,这个插件就处理了上面安卓平台的问题,功能还比官方的多很多

    • 插件库地址

    效果展示

    WebView页面.png

    依赖

    flutter_inappwebview: ^5.7.2+3
    

    首页

    import 'dart:io';
    import 'package:flutter/services.dart';
    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_web_view/browser_page.dart';
    
    void main() {
      _transparentStatusBar();
      runApp(const MyApp());
    }
    
    /// 透明状态栏
    void _transparentStatusBar() {
      if (!kIsWeb) {
        //Android平台 透明状态栏
        if (Platform.isAndroid) {
          SystemUiOverlayStyle systemUiOverlayStyle =
              const SystemUiOverlayStyle(statusBarColor: Colors.transparent);
          SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
        }
      }
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter WebView',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(title: 'Flutter WebView Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key? key, required this.title}) : super(key: key);
    
      final String title;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return const Center(
          child: BrowserPage("https://uniapp.dcloud.io/"),
        );
      }
    }
    

    WebView页面

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:flutter_inappwebview/flutter_inappwebview.dart';
    import 'dart:async';
    
    /// App内部Web浏览器页面
    class BrowserPage extends StatefulWidget {
      const BrowserPage(this.url, {Key? key}) : super(key: key);
    
      final String url;
    
      @override
      State createState() => _BrowserPageState();
    }
    
    /// 生成进度条组件,进度从0 ~ 1
    _createProgressBar(double progress, BuildContext context) {
      return LinearProgressIndicator(
        backgroundColor: Colors.white70.withOpacity(0),
        value: progress == 1.0 ? 0 : progress,
        valueColor: const AlwaysStoppedAnimation<Color>(Colors.blue),
      );
    }
    
    class _BrowserPageState extends State<BrowserPage> {
      InAppWebViewController? _webViewController;
      String? _webTitle;
      double _progress = 0;
      bool isCanGoBack = false;
      bool isCanForward = false;
    
      final InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
        crossPlatform: InAppWebViewOptions(
          useShouldOverrideUrlLoading: true,
          mediaPlaybackRequiresUserGesture: false,
        ),
    
        /// android 支持HybridComposition
        android: AndroidInAppWebViewOptions(
          useHybridComposition: true,
        ),
        ios: IOSInAppWebViewOptions(
          allowsInlineMediaPlayback: true,
        ),
      );
    
      Future<String?> getUrl() {
        if (_webViewController == null) {
          return Future.sync(() => null);
        }
        return _webViewController!.getUrl().then((uri) => uri.toString());
      }
    
      Future<void> loadUrl(String url) {
        if (_webViewController == null) {
          return Future.sync(() => null);
        }
        return _webViewController!
            .loadUrl(urlRequest: URLRequest(url: Uri.parse(url)));
      }
    
      @override
      Widget build(BuildContext context) {
        return WillPopScope(
            onWillPop: () {
              Future<bool> canGoBack = _webViewController!.canGoBack();
              return canGoBack.then((isCanGoBack) {
                if (isCanGoBack) {
                  _webViewController!.goBack();
                  return false;
                } else {
                  return true;
                }
              });
            },
            child: Scaffold(
              appBar: AppBar(
                leading: Row(
                  children: [
                    isCanGoBack
                        ? IconButton(
                            onPressed: () {
                              _webViewController?.goBack();
                            },
                            icon: const Icon(Icons.arrow_back))
                        : IconButton(
                            icon: const Icon(Icons.close),
                            onPressed: () {
                              SystemNavigator.pop();
                            })
                  ],
                ),
                title: Text(_webTitle ?? "FlutterWebView"),
              ),
              body: Column(
                children: [
                  Expanded(
                      child: Stack(
                    children: [
                      InAppWebView(
                        initialUrlRequest: URLRequest(url: Uri.parse(widget.url)),
                        initialOptions: options,
                        onWebViewCreated: (InAppWebViewController controller) {
                          _webViewController = controller;
                        },
                        onTitleChanged:
                            (InAppWebViewController controller, String? title) {
                          setState(() {
                            _webTitle = title ?? "";
                          });
                        },
                        onLoadStop: (InAppWebViewController controller, Uri? url) {
                          //页面加载完毕,显示隐藏AppBar的返回键
                          controller.canGoBack().then((canGoBack) => {
                                setState(() {
                                  isCanGoBack = canGoBack;
                                })
                              });
                          controller.canGoForward().then((canForward) => {
                                setState(() {
                                  isCanForward = canForward;
                                })
                              });
                        },
                        onProgressChanged:
                            (InAppWebViewController controller, int progress) {
                          //进度从0 ~ 100
                          setState(() {
                            _progress = progress / 100.0;
                          });
                        },
                      ),
                      _createProgressBar(_progress, context)
                    ],
                  ))
                ],
              ),
            ));
      }
    }
    

    相关文章

      网友评论

        本文标题:Flutter之WebView

        本文链接:https://www.haomeiwen.com/subject/jqvnudtx.html