Flutter InAppWebView Pluginの使い方について。
Flutter InAppWebView PluginはFlutterの多機能なWebViewのプラグイン。
要件
Flutter InAppWebView Pluginを使うための要件。
- Android
- minSdkVersion 17
- support for androidx
- iOS
- –ios-language swift
- Xcode version >= 12
インストール
flutter pub add flutter_inappwebview
設定
AndroidのminSdkVersionの設定
android/app/build.gradleを編集し、android.defaultConfig.minSdkVersionを17以上にする。
android {
defaultConfig {
// minSdkVersion flutter.minSdkVersion
minSdkVersion 17
Androidのネットワークの権限の設定
android/app/src/main/AndroidManifest.xmlを編集する。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.my_inappwebview_sample">
<uses-permission android:name="android.permission.INTERNET"/> // 追加
Androidのnet::ERR_CLEARTEXT_NOT_PERMITTEDエラー対策
開発サーバーはhttpなので、httpでアクセスできるようにする。
android/app/src/main/AndroidManifest.xmlを編集する。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.my_inappwebview_sample">
<application
android:label="my_inappwebview_sample"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true"> // 追加
iOSのATS対応
開発サーバーはhttpなので、httpでアクセスできるようにする。
ios/Runner/Info.plistに以下を追加する。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
</dict>
InAppWebViewを使う
InAppWebViewのパッケージをインポートする。
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
最初にWidgetsFlutterBinding.ensureInitialized()を呼ぶ。
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
ホームページを表示するシンプルなアプリの例。
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: "Flutter InAppWebView Sample",
home: SafeArea(
child: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Stack(
children: [
InAppWebView(
initialUrlRequest:
URLRequest(url: Uri.parse("https://www.gesource.jp/weblog/")),
),
],
);
}
}
UserAgentを設定する
InAppWebView(
initialUrlRequest:
URLRequest(url: Uri.parse("https://www.gesource.jp/weblog/")),
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
userAgent: "Flutter InAppWebView Sample",
)),
),
ディープリンク(Custom URL Scheme)でアプリを起動する
WebViewのshouldOverrideUrlLoadingイベントを取得できるように、useShouldOverrideUrlLoadingをtrueにする。
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
useShouldOverrideUrlLoading: true,
),
shouldOverrideUrlLoading()で、URLを判定する。
次のサンプルコードでは、URLがtest://youtueのとき、ブラウザを起動してYouTubeを開く。
URLを開くためにurl_launcherパッケージを使用している。
url_launcherのインストール
flutter pub add url_launcher
url_launcherのインポート
import 'package:url_launcher/url_launcher.dart';
サンプルコード
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Stack(
children: [
InAppWebView(
initialUrlRequest:
URLRequest(url: Uri.parse("https://www.gesource.jp/weblog/")),
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
useShouldOverrideUrlLoading: true,
),
),
shouldOverrideUrlLoading: (controller, navigationAction) async {
var uri = navigationAction.request.url!;
if ((uri.scheme == 'test') && (uri.host == "youtube")) {
await launchUrl(Uri.parse('https://www.youtube.com'), mode: LaunchMode.externalApplication);
return NavigationActionPolicy.CANCEL;
}
return NavigationActionPolicy.ALLOW;
},
),
],
);
}
}
inputタグで画像を選択する
「<input type=”file” accept=”image/*”>」で画像を選択する。
permission_handlerを使用する。
permission_handlerのインストール。
flutter pub add permission_handler
permission_handlerのインポート。
import 'package:permission_handler/permission_handler.dart';
import 'dart:async';
import 'package:permission_handler/permission_handler.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Permission.camera.request();
runApp(const MyApp());
}
Androidの設定
android/app/build.gradleを編集し、compileSdkVersionを33にする。
android {
// compileSdkVersion flutter.compileSdkVersion
compileSdkVersion 33
android/app/src/main/AndroidManifest.xmlを編集する。
<manifest >
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" /> // 追加
<application>
// ここから追加
<provider
android:name="com.pichillilorenzo.flutter_inappwebview.InAppWebViewFileProvider"
android:authorities="${applicationId}.flutter_inappwebview.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
// ここまで追加
iOSの設定
ios/Runner/Info.plistに以下を追加する。
<key>NSCameraUsageDescription</key>
<string>Flutter requires acess to camera.</string>
備考
Androidでは、アクティビティが破棄されるとファイルを選択できない。
ページ遷移(戻る、進む、指定のURLを表示)
ページ遷移には、InAppWebViewControllerを使用する。
サンプルコード
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:permission_handler/permission_handler.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Permission.camera.request();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: "Flutter InAppWebView Sample",
home: SafeArea(
child: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
InAppWebViewController? webViewController;
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
children: [
ElevatedButton(
onPressed: () {
webViewController?.goBack();
},
child: const Text("Back")),
ElevatedButton(
onPressed: () {
webViewController?.goForward();
},
child: const Text("Forward")),
ElevatedButton(
onPressed: () {
final url = URLRequest(
url: Uri.parse("https://www.gesource.jp/weblog/"));
webViewController?.loadUrl(urlRequest: url);
},
child: const Text("Blog")),
],
),
Expanded(
child: InAppWebView(
initialUrlRequest:
URLRequest(url: Uri.parse("https://www.gesource.jp/weblog/")),
onWebViewCreated: (controller) {
webViewController = controller;
},
)),
],
);
}
}