flutter使用webview_flutter

一、webview_flutter引入

官网文档:https://pub-web.flutter-io.cn/packages/webview_flutter

dependencies:
	webview_flutter: ^4.4.1

二、使用demo

controller = WebViewController()
  ..setJavaScriptMode(JavaScriptMode.unrestricted)
  ..setBackgroundColor(const Color(0x00000000))
  ..setNavigationDelegate(
    NavigationDelegate(
      onProgress: (int progress) {
        // Update loading bar.
      },
      onPageStarted: (String url) {},
      onPageFinished: (String url) {},
      onWebResourceError: (WebResourceError error) {},
      onNavigationRequest: (NavigationRequest request) {
        if (request.url.startsWith('https://www.youtube.com/')) {
          return NavigationDecision.prevent;
        }
        return NavigationDecision.navigate;
      },
    ),
  )
  ..loadRequest(Uri.parse('https://flutter.cn'));

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: const Text('Flutter Simple Example')),
    body: WebViewWidget(controller: controller),
  );
}
//安卓sdk版本配置
android {
    defaultConfig {
        minSdkVersion 19
    }
}

三、AndroidManifest.xml配置http网页访问

访问https网页可以不加,http必须加,不然报错

<application
        android:usesCleartextTraffic="true">

四、网页电话拨打配置

不加点击网页上的拨打电话会报错

//用于拨打电话,当然也可以打开网页
dependencies:
	url_launcher: ^6.0.9
onNavigationRequest: (request) async {
                if (request.url.startsWith("mailto") || request.url.startsWith("tel") || request.url.startsWith("sms")) {
                  var phone = Uri.parse('tel:${request.url}');
                  if (await canLaunchUrl(phone)) {
                    await launchUrl(phone);// 跳转到拨号页面
                  }
                  return NavigationDecision.prevent;
                } else {
                  return NavigationDecision.navigate;
                }
              },

五、网页返回和网页关闭

//首先关闭页面左上角的返回按钮
	appBar: AppBar(
        centerTitle: true,
        title: Text(widget.title),
        automaticallyImplyLeading: false,
        leading: InkWell(
          onTap: () {
            Navigator.of(context).pop();
          },
          child: Icon(Icons.close),
        )
      )
//拦截返回手势,进行判断
			WillPopScope(
                onWillPop: () async {
                  var canBack = await controller.canGoBack();
                  if (canBack) {
                    // 当网页还有历史记录时,返回webview上一页
                    await controller.goBack();
                  } else {
                    // 返回原生页面上一页
                    Navigator.of(context).pop();
                  }
                  return false;
                },
                child: WebViewWidget(
                    controller: controller
                ),
              )

六、源码

Navigator.of(context).push(MaterialPageRoute(builder: (context) {
                   return WebviewPage2(url: "https://www.xx.cn", title: "标题");
                 }));
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:webview_flutter/webview_flutter.dart';

//webview展示公共页面
class WebviewPage2 extends StatefulWidget {
  WebviewPage2({
    Key? key,
    required this.url,
    required this.title
  }) : super(key: key);

  final String url;
  final String title;

  
  State<StatefulWidget> createState() => _WebviewPage2State();
}

class _WebviewPage2State extends State<WebviewPage2> {
  late WebViewController controller;
  RxDouble _progress = 0.0.obs;
  RxBool _isShow = false.obs;

  
  void initState() {
    super.initState();
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(
          NavigationDelegate(
              onNavigationRequest: (request) async {
                if (request.url.startsWith("mailto") || request.url.startsWith("tel") || request.url.startsWith("sms")) {
                  var phone = Uri.parse('tel:${request.url}');
                  if (await canLaunchUrl(phone)) {
                    await launchUrl(phone);// 跳转到拨号页面
                  }
                  return NavigationDecision.prevent;
                } else {
                  return NavigationDecision.navigate;
                }
              },
              onProgress: (int progress) {
                _progress.value = progress / 100;
              },
              onPageStarted: (String url) {
              },
              onPageFinished: (String url) {
                _isShow.value = true;
              }
          )
      )
      ..loadRequest(Uri.parse(widget.url));
  }

  
  void dispose() {
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text(widget.title),
        automaticallyImplyLeading: false,
        leading: InkWell(
          onTap: () {
            Navigator.of(context).pop();
          },
          child: Icon(Icons.close),
        )
      ),
      body: Column(
        children: [
          Obx(() => Offstage(
            offstage: _isShow.value,
            child: LinearProgressIndicator(
              value: _progress.value,
              color: Colors.yellow,
              minHeight: 4,
            ),
          )),
          Expanded(
              child: WillPopScope(
                onWillPop: () async {
                  var canBack = await controller.canGoBack();
                  if (canBack) {
                    // 当网页还有历史记录时,返回webview上一页
                    await controller.goBack();
                  } else {
                    // 返回原生页面上一页
                    Navigator.of(context).pop();
                  }
                  return false;
                },
                child: WebViewWidget(
                    controller: controller
                ),
              )
          ),
        ],
      ),
    );
  }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值