なぜflutter_inappwebviewを使うことにしたのか
flutter_inappwebview 公式ドキュメント
https://pub.dev/packages/flutter_inappwebview
今までWebViewを表示する際には公式に提供されているflutter_webviewライブラリしか使っておらず、特に不満もなかったので、あまりflutter_webview以外に関心を持っていませんでした。
しかし以前、以下の記事を書いた時、flutter_webviewに初めて物足りなさを感じました。
具体的には、LinearLoadingIndicatorで読み込み状態であることを表示するまでは良かったのですが、webview_flutterではLoadingの進行度を取得出来ず、「読み込み中、ずっとLinearLoadingIndicatorが動き続ける」という実装が限界でした。
webview_flutterでは「Loadingを開始する時」「Loadingを完了した時」のイベントしか取得出来ないからです。
ではどうやって実現しようかと調べてみると、別のライブラリを使う必要がありそうだと判明しました。そこで今回使用するflutter_inappwebviewライブラリや、flutter_webview_pluginというライブラリがヒットしました。flutter_webview_pluginでも今回やりたいことは実現出来ますが、ライブラリの最新アップデートが2020年の4月で、あまりメンテされていないような印象を受けたので今回はflutter_inappwebviewを使うことにしました。
準備
上記の自分の過去記事でも使用した以下のコードをベースに実装を進めます。(QiitaのFlutterの最新記事を取得して、記事をタップすると記事の詳細が表示されるという内容です)
まずはライブラリのインストールのため、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に変更する必要があります。
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ファイルを変更します。
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;
});
},
),
),
],
),
);
}
}
分かりづらいですが、記事の詳細画面を開いた時にLoadingの進行に合わせて、AppBar下のインジケーターのバーが変化しているのが分かります。
(後述しますが、iOSの上下端であることを示すアニメーションがなくなっています。)
flutter_webviewとの比較
まずスクロール感に関してはflutter_inappwebviewでもflutter_webviewでも、またiOSでもAndroidでも違いは全く分かりませんでした。
flutter_inappwebviewはflutter_webviewより多機能なので、全てにおいて優れているかというと、そうではありませんでした。それはiOSでflutter_inappwebviewを使用した場合に上下の端であることを示すアニメーションが発生しません。
あまり大きな問題ではありませんが、気になると言えば少し気になります。この辺iOSのWebViewだとどういう動きか少し気になります。
上のキャプチャはflutter_webviewでiOSで上下端のスクロールを行った場合です。上下の端を超えてスクロールしようとすると、戻るようなアニメーションがあります。
Androidではflutter_webviewとflutter_inappwebviewで特に動きに差は感じませんでした。
まとめ
現状、flutter_webviewとflutter_inappwebviewのどちらを使うのが良いかと考えた場合、その時の環境や条件も関係してくると思うので、一概にどちらが良いか断言することは難しいです。
私自身はLoadingの進行度は欲しい情報ではあるので、flutter_webviewでそこが対応されるまでは、いったんflutter_inappwebviewを使っていこうかと考えています。
また他にもflutter_inappwebviewには様々な種類の機能があり、色々遊べそうではあるので、私も触っていくうちに役に立つ機能を見つけたら共有したいです。
今回作成したコード