WebViewの高さをローディング時に動的に変える方法

はじめに

2021年度アドベントカレンダーの2日目の担当の高野です。メディア事業部のアプリではWebViewを使うことが多く、その備忘録として残します。

動作バージョン

Flutter 2.5.1
Dart 2.14.0
webview_flutter 2.1.1

実装

今回はwebview_flutterを使用していますが、他のWebViewライブラリでもおそらく同じだと思います。
まず初めに動的にWebViewの高さを変更するためにはSizedBoxまたはContainerでWebViewを包みます。

Container(
  height: controller.webViewHeight.value,
  child: WebView(
    navigationDelegate: (request) => controller.onRequestNavigation(request: request),
    javascriptMode: JavascriptMode.unrestricted,
    onPageFinished: (_) => controller.onPageFinished(),
    onWebViewCreated: (webViewController) => controller.onWebViewCreated(controller: webViewController),
  ),
);

ここのheightにWebViewの高さを取得した後に入れることで動的に高さを変えることができます。
このWebViewのonPageFinishedの発火時に以下コードを発火させることによって取得できます。Javascriptを使用するので JavascriptMode.unrestrictedjavascriptMode に指定しておいてください。

Future<double> _getWebViewHeight() async {
  try {
    final rawWebviewHeight = await controller!.evaluateJavascript('document.body.offsetHeight;');
    final webviewHeight = double.parse(rawWebviewHeight);
    return webviewHeight;
  } catch (e) {
    Logger.error(e);
    return 1000;
  }
}

これであとはこの関数の返り値をContainerやSizedBoxのheightに指定してあげれば取得時にbuild()が走るので更新が行われます。

まとめ

どこが一番重要かと言うと

await controller!.evaluateJavascript('document.body.offsetHeight;');

ここですね、これによってロードしたページ(body)の高さを取得することができます。

最後に、弊社では採用もバシバシ実施しているので興味のあるかたがいましたらご応募ください。
https://www.wantedly.com/companies/excite

Advent Calendar 2021を引き続き楽しんでいただけると嬉しいです。