本教程教大家如何在Flutter中打开网页url。

可随意转载!

前言

我们知道Android和iOS系统都定义了一些schema可以用来给App截获的,比如网页、sms、电话。手机操作系统会用合适的App打开它们。本教程教大家如何在Flutter中打开网页url。

创建项目

命令行执行以下命令:

flutter create -a java -i objc ability_url_lancher

创建flutter项目,并且指定Android平台的编程语言为Java,iOS平台的编程语言为Objective-C。

打开Android Studio,选择Open an exist Android Studio Project

配置项目

编辑flutter配置文件pubspec.yaml ,如下图:

点击Package get链接,执行命令, 获取到pub.dev上的官方插件包。

编写main.dart

1. import依赖包

import 'dart:async';
import 'package:url_launcher/url_launcher.dart';

2. 定义类变量

定义类型为Future的私有变量

  Future<void> _launched;

3. 定义操作函数-返回Future对象

  Future<void> _launchInBrowser(String url) async {
    if (await canLaunch(url)) {
      await launch(
        url,
        forceSafariVC: false,
        forceWebView: false,
        headers: <String, String>{'user': 'ouyangshixiong'},
      );
    } else {
      throw 'Could not launch $url';
    }
  }

  Future<void> _launchInWebViewOrVC(String url) async {
    if (await canLaunch(url)) {
      await launch(
        url,
        forceSafariVC: true,
        forceWebView: true,
        headers: <String, String>{'user': 'ouyangshixiong'},
      );
    } else {
      throw 'Could not launch $url';
    }
  }

4. 定义FutureBuilder

函数定义:
FutureBuilder({future, builder})

参数builder为函数参数(dart支持函数作为参数):
Function( BuildContext context, AsyncSnapshot snapshot )

FutureBuilder会依赖上面的Future。下面是本教程中的builder:

  /// 显示网页的加载状态
  Widget _launchStatus(BuildContext context, AsyncSnapshot<void> snapshot) {
    if (snapshot.hasError) {
      return Text('Error: ${snapshot.error}');
    } else {
      return const Text('');
    }
  }

FutureBuilder的执行过程: future+builder为两个异步函数。它们会同时执行。builder会根据future的实时状态来显示Text文本。效果就是一边加载百度,一边显示空,如果加载失败则显示错误信息。

扩展阅读:StreamBuilder跟它是非常相似,唯一的区别是StreamBuilder返回的是Steam对象。

5. 定义Flutter的UI方法

  @override
  Widget build(BuildContext context) {
    const String toLaunch = 'https://m.baidu.com/';
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView(
        children: <Widget>[
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Padding(
                padding: EdgeInsets.all(16.0),
                child: Text(toLaunch),
              ),
              RaisedButton(
                onPressed: () => setState(() {
                  _launched = _launchInBrowser(toLaunch);
                }),
                child: const Text('用手机浏览器打开百度'),
              ),
              const Padding(padding: EdgeInsets.all(16.0)),
              RaisedButton(
                onPressed: () => setState(() {
                  _launched = _launchInWebViewOrVC(toLaunch);
                  Timer(const Duration(seconds: 5), () {
                    print('Closing WebView after 5 seconds...');
                    closeWebView();
                  });
                }),
                child: const Text('用webview打开百度'),
              ),
              const Padding(padding: EdgeInsets.all(16.0)),
              /// 注意这行
              FutureBuilder<void>(future: _launched, builder: _launchStatus),
            ],
          ),
        ],
      ),
    );
  }

注意:In app webview中只能打开https网页,http网页因为安全问题可能被禁止。即使url跳转中有过http链接也不行。

真机调试

1. 验证App内打开浏览器,指向百度

2. 使用webview打开百度的效果

机型适配问题

无,适配所有Android和iOS机型

示例源代码

源码地址