flutter_webviewの代わりに、flutter_inappwebviewを使ってみた（Loading進行度の取得）

## なぜflutter_inappwebviewを使うことにしたのか

flutter_inappwebview　公式ドキュメント
https://pub.dev/packages/flutter_inappwebview

今までWebViewを表示する際には公式に提供されているflutter_webviewライブラリしか使っておらず、特に不満もなかったので、あまりflutter_webview以外に関心を持っていませんでした。

しかし以前、以下の記事を書いた時、flutter_webviewに初めて物足りなさを感じました。

- [webview_flutterで読み込みインジケーターを表示する](https://qiita.com/toda-axiaworks/items/ea9482f90dd3164ab9eb)

具体的には、LinearLoadingIndicatorで読み込み状態であることを表示するまでは良かったのですが、webview_flutterではLoadingの進行度を取得出来ず、「読み込み中、ずっとLinearLoadingIndicatorが動き続ける」という実装が限界でした。
webview_flutterでは「Loadingを開始する時」「Loadingを完了した時」のイベントしか取得出来ないからです。

ではどうやって実現しようかと調べてみると、別のライブラリを使う必要がありそうだと判明しました。そこで今回使用するflutter_inappwebviewライブラリや、[flutter_webview_plugin](https://pub.dev/packages/flutter_webview_plugin)というライブラリがヒットしました。flutter_webview_pluginでも今回やりたいことは実現出来ますが、ライブラリの最新アップデートが2020年の4月で、あまりメンテされていないような印象を受けたので今回はflutter_inappwebviewを使うことにしました。

## 準備

上記の自分の過去記事でも使用した以下のコードをベースに実装を進めます。（QiitaのFlutterの最新記事を取得して、記事をタップすると記事の詳細が表示されるという内容です）

https://github.com/toda-axia/qiita_sample/tree/feature/async_value

まずはライブラリのインストールのため、pubspec.yamlを更新します。

```pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  flutter_riverpod: ^0.12.1
  retrofit: ^1.3.4+1
  freezed_annotation: ^0.12.0
  logging: ^0.11.4
  pretty_dio_logger: ^1.1.1
  webview_flutter: ^1.0.7 # こちらは今回削除して良い
  flutter_inappwebview: ^4.0.0+4 #これを追加する必要がある
  state_notifier: ^0.6.0
  flutter_state_notifier: ^0.6.1

```

またAndroidで動作させる場合は、android/app/src/build.gradleのminSdkVersionを17に変更する必要があります。

```app/build.gradle
defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.wumpuss.qiita_sample"
        minSdkVersion 17  // 16→17に変更する
        targetSdkVersion 28
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }

```

## 変更内容

記事の詳細を表示するためのarticle_detail_view.dartファイルを変更します。

```article_detail_view.dart
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:qiita_sample/data/entities/qiita_info.dart';

class ArticleDetailScreen extends StatefulWidget {
  ArticleDetailScreen({
    @required this.qiitaInfo,
  });

  final QiitaInfo qiitaInfo;

  @override
  _ArticleDetailScreenState createState() => _ArticleDetailScreenState();
}

class _ArticleDetailScreenState extends State<ArticleDetailScreen> {
  double progress = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          widget.qiitaInfo.title,
          overflow: TextOverflow.ellipsis,
          style: TextStyle(
            fontSize: 13,
          ),
        ),
      ),
      body: Column(
        children: [
          progress < 1.0 ? LinearProgressIndicator(value: progress) : SizedBox.shrink(),
          Expanded(
            child: InAppWebView(
              initialUrl: widget.qiitaInfo.url,
              onProgressChanged: (_, int progress) {
                setState(() {
                  this.progress = progress / 100;
                });
              },
            ),
          ),
        ],
      ),
    );
  }
}
```

![20201229_3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479957/712658d8-30ce-0f6f-aa97-e37d265c63ba.gif)

分かりづらいですが、記事の詳細画面を開いた時にLoadingの進行に合わせて、AppBar下のインジケーターのバーが変化しているのが分かります。
（後述しますが、iOSの上下端であることを示すアニメーションがなくなっています。）

## flutter_webviewとの比較

まずスクロール感に関してはflutter_inappwebviewでもflutter_webviewでも、またiOSでもAndroidでも違いは全く分かりませんでした。

flutter_inappwebviewはflutter_webviewより多機能なので、全てにおいて優れているかというと、そうではありませんでした。それはiOSでflutter_inappwebviewを使用した場合に上下の端であることを示すアニメーションが発生しません。
あまり大きな問題ではありませんが、気になると言えば少し気になります。この辺iOSのWebViewだとどういう動きか少し気になります。

![20201229_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479957/e1f86b94-2d99-217e-044f-331f59425eae.gif)


上のキャプチャはflutter_webviewでiOSで上下端のスクロールを行った場合です。上下の端を超えてスクロールしようとすると、戻るようなアニメーションがあります。
Androidではflutter_webviewとflutter_inappwebviewで特に動きに差は感じませんでした。


## まとめ
現状、flutter_webviewとflutter_inappwebviewのどちらを使うのが良いかと考えた場合、その時の環境や条件も関係してくると思うので、一概にどちらが良いか断言することは難しいです。

私自身はLoadingの進行度は欲しい情報ではあるので、flutter_webviewでそこが対応されるまでは、いったんflutter_inappwebviewを使っていこうかと考えています。

また他にもflutter_inappwebviewには様々な種類の機能があり、色々遊べそうではあるので、私も触っていくうちに役に立つ機能を見つけたら共有したいです。

## 今回作成したコード

https://github.com/toda-axia/qiita_sample/tree/feature/show_indicator_in_webview