Flutter WebViewのURL遷移をフックする

こんにちは、株式会社Pentagonでエンジニアをしている日浦です。

・FlutterでのwebViewの表示、URL遷移のフック方法について記載します。

【こんな人に読んで欲しい】

  • webViewアプリを作成しようと思っている人
  • webViewでのイベントをフックしてネイティブで処理したい人

【この記事を読むメリット】

  • webViewアプリを作成するなど、イベントをフックしたい場面が出てくるところで、この記事の内容を活用できます。

【結論】

  • webViewのリンクURLからqueyなどを取得したり、遷移を制御したりできます。

Swiftでの開発とほぼ同じことができそうですね。

目次

packageをinstall

  • webview_flutter を install する

pubspec.yaml に webview_flutter を追記します。

dependencies:
  flutter:
    sdk: flutter
  webview_flutter:

webViewをWidgetを作成


class WebViewScreen extends StatefulWidget {
  @override
  _WebViewScreenState createState() => _WebViewScreenState();
}

class _WebViewScreenState extends State<WebViewScreen> {
  String _title = '';
  @override
  void initState() {
    super.initState();
    if (Platform.isAndroid) {
      WebView.platform = SurfaceAndroidWebView();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_title),
      ),
      body: WebView(
        //表示したいurlを指定
        initialUrl: 'https://www.google.com',
        // javascriptを有効化
        javascriptMode: JavascriptMode.unrestricted,
        // ページの読み込み開始
        onPageStarted: (String url) {
          print('Page started loading: $url');
          final uri = Uri.parse(url);
          print(uri.host);
          print(uri.path);
          print(uri.query);
          print(uri.queryParameters);
        },
        // ページの読み込み完了
        onPageFinished: (String url) {
          print('Page finished loading: $url');
        },
        gestureNavigationEnabled: true,
      ),
    );
  }
}
  • onPageStartedページのロードが開始された時のハンドラで
    url を final uri = Uri.parse(url); parseすることでqueryなど特定の値を取得できます。

WebViewController を使ってページタイトルを取得してみる

final Completer<WebViewController> _controller =
      Completer<WebViewController>();
 WebView(
        //表示したいurlを指定
        initialUrl: 'https://www.google.com',
        // javascriptを有効化
        javascriptMode: JavascriptMode.unrestricted,
        // controllerを登録
        onWebViewCreated: _controller.complete,
        // ページの読み込み開始
        onPageStarted: (String url) {
          print('Page started loading: $url');
        },
        // ページの読み込み完了
        onPageFinished: (String url) async {
          print('Page finished loading: $url');

          // ページタイトル取得
          final controller = await _controller.future;
          final title = await controller.getTitle();
          setState(() {
            if (title != null) {
              _title = title;
            }
          });
        },
        gestureNavigationEnabled: true,
      ),
  • WebViewController を使うとページタイトルを取得することができました!

特定のURLを外部ブラウザで開く

  • navigationDelegateを実装する
navigationDelegate: (NavigationRequest request) async {
          if (request.url.startsWith('https://m.youtube.com/')) {
            if (await canLaunch(request.url)) {
              await launch(
                request.url,
                forceSafariVC: false,
              );
            }
            return NavigationDecision.prevent;
          }
          return NavigationDecision.navigate;
        },
  • NavigationDecision.prevent を返すとwebView内で遷移しない
  • NavigationDecision.navigate を返すと通常通り遷移

今回はURLがyoutubeの場合、外部アプリで開くようにしてみました。
url_launcher を使用。

まとめ

Flutter公式のwebview_flutter を使ってwebViewの操作を実装してみました。
やりたいことは十分できて簡単かなといったところ。
Swiftでの開発とほぼ同じことができそうで安心しました。

採用情報はこちら
目次