Flutter:webview_flutter插件使用

一、添加权限:

1.Android网络权限(工程/android/app/src/main/AndroidManifest.xml):

<manifest ...>
    ...
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

2.iOS添加使用说明(工程/ios/Runner/Info.plist):

<dict>
    ...
    <key>io.flutter.embedded_views_preview</key>
    <string>YES</string>
</dict>

二、使用WebView显示网页:

1.添加webview_flutter插件依赖,在pubspec.yaml中:

dependencies:
  webview_flutter: ^3.0.4  #WebView插件

2.使用WebView显示网页:

class WebViewPage extends StatefulWidget { //网页显示界面
  const WebViewPage({Key? key, required this.url}) : super(key: key); //外部传入URL
  final String url;
  @override
  State<WebViewPage> createState() => _PageState();
}
class _PageState extends State<WebViewPage> {
  late WebViewController _webControl; //WebView控制类
  final CookieManager _cookieManager = CookieManager();
  late double progress = 0.01;  //H5加载进度值
  final double VISIBLE = 1;
  final double GONE = 0;
  late double progressHeight = GONE; //H5加载进度条高度
  //显示或隐藏进度条
  void setProgressVisible(double isVisible) {
    setState(() {
      progressHeight = isVisible;
    });
  }
  @override
  void initState() {
    super.initState();
    if (Platform.isAndroid)  WebView.platform = SurfaceAndroidWebView();  //android平台时使用SurfaceAndroidWebView
  }
  WebView _createWebView(){
    return WebView( //WebView组件
      initialUrl: widget.url,             //设置URL地址
      javascriptMode: JavascriptMode.unrestricted,  //启用JS
      onWebViewCreated: (WebViewController webControl) { //WebView创建时触发
        _webControl = webControl;
      },
      javascriptChannels: <JavascriptChannel>{getJSChannel1(context), getJSChannel2(context)}, //添加JS方法(可以多个),实现与H5交互数据
      navigationDelegate: (NavigationRequest request) { //控制页面是否进入下页
        if (request.url.startsWith('http://www.yyh.com')) {
          return NavigationDecision.prevent; //禁止跳下页
        }
        return NavigationDecision.navigate; //放行跳下页
      },
      onPageStarted: (String url) { //H5页面开始加载时触发
        setProgressVisible(VISIBLE); //显示加载进度条
      },
      onProgress: (int progress) { //加载H5页面时触发多次,progress值为0-100
        this.progress = progress.toDouble() / 100.0;  //计算成0.0-1.0之间的值
      },
      onPageFinished: (String url) { //H5页面加载完成时触发
        setProgressVisible(GONE); //隐藏加载进度条
      },
      gestureNavigationEnabled: true,  //启用手势
    );
  }
  //添加JS方法1,与H5交互数据
  JavascriptChannel getJSChannel1(BuildContext context) {
    return JavascriptChannel(
        name: 'jsMethodName1',  //方法名,与H5中的名称一致。H5中调用方式:js方法名1.postMessage("字符串");
        onMessageReceived: (JavascriptMessage message) { //接收H5发过来的数据
          String json = message.message;
          print("H5发过来的数据1: $json");
        });
  }
  //添加JS方法2,与H5交互数据
  JavascriptChannel getJSChannel2(BuildContext context) {
    return JavascriptChannel(
        name: 'jsMethodName2',
        onMessageReceived: (JavascriptMessage message) {
          String json = message.message;
          print("H5发过来的数据2: $json");
        });
  }
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
        onWillPop: () async {  //拦截页面返回事件
          if (await _webControl.canGoBack()) {
            _webControl.goBack(); //返回上个网页
            return false;
          }
          return true; //退出当前页
        },
        child: Scaffold(
            appBar: AppBar(title: const Text('WebView使用')),
            body: Stack(
              children: [
                _createWebView(), //WebView
                SizedBox(        //进度条
                    height: progressHeight,
                    child: LinearProgressIndicator(
                      backgroundColor: Colors.white,
                      valueColor: AlwaysStoppedAnimation(Colors.yellow),
                      value: progress, //当前加载进度值
                    ))
              ],
            )));
  }
}

三、WebView常用方法:

1.加载Html的几种方式:

(1)加载Html字符串:

String htmlString = '''
  <!DOCTYPE html><html>
  <head><title>Navigation Delegate Example</title></head>
  <body>
  加载Html内容
  </body>
  </html>
  ''';

方式1:

Future<void> loadHtmlString1() async {
  String content = base64Encode(const Utf8Encoder().convert(htmlString));
  await _webControl.loadUrl('data:text/html;base64,$content');
}

方式2:

Future<void> loadHtmlString2() async {
  await _webControl.loadHtmlString(htmlString);
}

(2)加载Html文件:

资源文件方式:

Future<void> loadHtmlFile1() async {
  await _webControl.loadFlutterAsset('assets/www/index.html');
}

File方式:

Future<void> loadHtmlFile2() async {
  String dir = (await getTemporaryDirectory()).path;
  File file = File(<String>{dir, 'www', 'index.html'}.join(Platform.pathSeparator));
  await file.create(recursive: true);
  String filePath = file.path;
  await file.writeAsString(htmlString);  //将html字符串写入文件
  await _webControl.loadFile(filePath);  //加载html文件
}

(3)加载HTTP请求:

Future<void> loadHttpRequest(String url, String json) async {
  final WebViewRequest request = WebViewRequest(
    uri: Uri.parse(url), //设置URL
    method: WebViewRequestMethod.post,  //设置请求方式,post或get请求
    headers: <String, String>{'Content-Type': 'application/json'},  //请求头字段
    body: Uint8List.fromList(json.codeUnits),  //请求参数
  );
  await _webControl.loadRequest(request); //加载HTTP请求
}

2.运行JS代码:

Future<void> runJSCode() async { //运行JS代码,模拟H5与Flutter交互数据
  await _webControl.runJavascript('jsMethodName1.postMessage("字符串");');  //此处模拟调用Flutter中定义的JS方法
}

3.Cookie添加/获取/清空:

//添加cookie
Future<void> addCookie() async {
  await _cookieManager.setCookie(const WebViewCookie(name: 'key1', value: 'value1', domain: 'url域名', path: '/路径'));
}
//获取cookie列表
Future<List<String>> getCookieList() async {
  String cookies = await _webControl.runJavascriptReturningResult('document.cookie');
  if (cookies == null || cookies == '""') <String>[];
  return cookies.split(';'); //获取cookie列表
}
//清空cookie
Future<void> clearCookies(BuildContext context) async {
  await _cookieManager.clearCookies();
}

4.缓存对象添加/获取/清空:

//添加缓存对象
Future<void> addCache() async {//caches.open()创建缓存对象, 存在时不创建
  await _webControl.runJavascript('caches.open("缓存对象名"); localStorage["key1"] = "value1";');
}
//获取缓存对象
Future<void> getCacheList() async {
  await _webControl.runJavascript('caches.keys()'
      '.then((cacheKeys) => JSON.stringify({"cacheKeys" : cacheKeys, "localStorage" : localStorage}))'
      '.then((caches) => jsMethodName1.postMessage(caches))');  //获取H5缓存对象,调用定义的JS方法发给Flutter
}
//清空缓存对象
Future<void> clearCache() async {
  await _webControl.clearCache();
}

猜你喜欢

转载自blog.csdn.net/a526001650a/article/details/127786060