Flutter でよく使われるパッケージ
はじめに
私は普段 Flutter を使用したアプリ開発をしております。
今回は Flutter 開発でよく使用される便利なパッケージを簡単に紹介していきます。
内容は初学者の方に向けたものなっていますので、すでに Flutter で開発をされている方には既知のものばかりだと思います!笑
それでは早速、各パッケージについてみていきましょう。
状態管理パッケージ
riverpod
Flutter といえば!というぐらい有名なパッケージですね。
状態管理ができるパッケージです。
**Provider
をグローバルに定義して使用します。
記事執筆の2023年7月時点では下記の種類があります。
- ✅ Provider
- ✅ (Async)NotifierProvider
- 👀 StateNotifierProvider
- ✅ FutureProvider
- ✅ StreamProvider
- ✅ StateProvider
- 👀 ChangeNotifierProvider
riverpod 使用例
簡単な例としてcounterProvider
という int
を保持する Provider
を作成し、データの更新と表示を行います。
処理の流れは以下です。
-
floatingActionButton
が押される -
counterProvider
の保持している値がインクリメントされる - View が更新される
// プロバイダーをグローバルに定義する
final counterProvider = StateProvider<int>((ref) => 0);
class MyHomePage extends ConsumerWidget {
const MyHomePage({
super.key,
});
Widget build(BuildContext context, WidgetRef ref) {
final counter = ref.watch(counterProvider);
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// Provider の値を更新
ref.read(counterProvider.notifier).update((state) => state + 1);
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
riverpod
は状態管理だけでなく、Dependency injection(依存性の注入)ができ、テストする際にも役立ちます。
こちらのサイトで軽く触れられていますが、ProviderScope
の overrides
を使用して DI を実現します。
コード生成系パッケージ
freezed
便利なコードジェネレーターです。
アプリ内で使用する「モデル」クラスを定義する際に、freezed を使用して定義・生成することで簡単に以下の恩恵が受けられます。
- イミュータブルなクラスを生成
- オブジェクトのクローンを作成する
copyWith
メソッドを実装 - シリアル化 / デシリアル化(toJson / fromJson)を実装
これらの機能を持ったクラスを普通に定義した場合数百行かかります。
下記の画像がイメージしやすく、左が普通に定義、右が freezed
を使用して定義した例です。
一目瞭然で「モデル」クラスを定義するのが楽になります。
先ほど紹介した riverpod
パッケージではイミュータブルな値の状態を保持します。
そのため copyWith
メソッドが大変便利です。(必要不可欠レベルで)
詳しくは下記を確認してください。
flutter_gen
リソースを管理するためのパッケージです。
主に、アセット(画像やフォント)や色などをコードで利用できるようにするパッケージです。
具体的には、設定ファイル (pubspec.yaml
もしくは flutter_gen.yaml
) を元に、リソースへの参照をコード生成することで、タイポの心配なくリソースを使用することができます。
flutter_gen 設定例
まずは、pubspec.yaml
にアセットを追加します。
flutter:
assets:
- assets/images/profile.jpg
次に、コマンドを実行します。
flutter pub get
flutter pub run flutter_gen:generate
これにより gen
フォルダが生成され、その中にリソースへの参照が含まれたコードが作成されます。
flutter_gen 使用例
生成されたコードを使うと、アセットの使用が簡単になります。
例えば、以下のように画像を表示できます。
Widget build(BuildContext context) {
// 使用方法1
return Assets.images.profile.image();
}
Widget build(BuildContext context) {
// 使用方法2
return Image.asset(Assets.images.profile.path);
}
このようにしてアセットを参照することで、存在しないアセット名を参照するミスを防ぐことができます。
ローカルデータストレージパッケージ
shared_preferences
Flutter のキーバリューストレージのためのパッケージです。Android の SharedPreferences
と iOS の NSUserDefaults
にアクセスするためのラッパーとなっています。
このパッケージを使うと、一部のデータをデバイスに永続的に保存し、アプリを閉じてもそのデータを保持することができます。例えば、ユーザの設定や、ログイン情報などの永続化が必要な情報を保存するのに適しています。
ただし、大量のデータや複雑なデータ構造を保存するためには適しておらず、そのようなケースではデータベースを使用することを検討するべきです。
shared_preferences 使用例
この例では、counter
の値を SharedPreferences
に保存し、アプリを再起動した際もその値を保持しています。initState
メソッド内で SharedPreferences
を読み込み、counter
の値を設定しています。そして、フローティングアクションボタンを押すたびに counter
の値を増やし、それを SharedPreferences
に保存しています。
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class SharedPreferencesDemo extends StatefulWidget {
SharedPreferencesDemo({Key? key}) : super(key: key);
_SharedPreferencesDemoState createState() => _SharedPreferencesDemoState();
}
class _SharedPreferencesDemoState extends State<SharedPreferencesDemo> {
int counter = 0;
void initState() {
super.initState();
_loadCounter();
}
_loadCounter() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
counter = (prefs.getInt('counter') ?? 0);
});
}
_incrementCounter() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
counter++;
prefs.setInt('counter', counter);
setState(() {});
}
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('Pressed $counter times.')),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
コード整理系パッケージ
import_sorter と import_path_converter
今回は二つのパッケージを紹介します。
どちらも import 文を統一してくれるものです。
下記のような要望があれば使用するぐらいで絶対必要なものではないです。
- 絶対パスと相対パスが混在していて気持ちが悪い。
- プロジェクト内で統一したい
import_sorter
は名前の通り import 文を並び替えてくれるパッケージです。
並び替えのビフォーアフター
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/physics.dart';
import 'package:flutter/painting.dart';
import 'package:intl/intl.dart';
import 'package:mdi/mdi.dart';
import 'package:provider/provider.dart';
import 'anotherFile.dart';
import 'package:example_app/anotherFile2.dart';
import 'dart:async';
import 'dart:io';
import 'dart:js';
// Dart imports:
import 'dart:async';
import 'dart:io';
import 'dart:js';
// Flutter imports:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/physics.dart';
// Package imports:
import 'package:intl/intl.dart';
import 'package:mdi/mdi.dart';
import 'package:provider/provider.dart';
// Project imports:
import 'package:example_app/anotherFile2.dart';
import 'anotherFile.dart';
import_path_converter
は import 文を 相対パス <-> 絶対パス に自動変換するパッケージです。
import 分を絶対パスに変換
import 'common/constants.dart' ;
import '../app.dart';
import 'package:example/common/constants.dart';
import 'package:example/app.dart';
もしプロジェクトメンバーで使用している IDE が VSCode で統一されているのであれば、これらのパッケージを導入せず Lint ルールと VSCode の設定で同様のことが可能です。
詳しくはこちらの記事が参考になります。
今回紹介した二つのパッケージはどちらもコマンドで動作します。
私は面倒くさがりなので lefthook
を導入して、git commit
前に自動的にコマンドを実行してくれるように設定しています。
lefthook
については記事の本筋とズレるのでこちらの記事に委譲します。
その他便利パッケージ
flutter_native_splash
アプリを起動する時に表示されるスプラッシュスクリーンを簡単に実装、カスタマイズできるパッケージです。
pubspec.yaml
ファイルに設定を記述し、コマンドを実行するだけで、Android、iOS、Web、それぞれのスプラッシュスクリーンの実装が簡単にできます。
flutter_native_splash 使用例
pubspec.yaml
ファイルにスプラッシュスクリーンの設定を記述します。
flutter_native_splash:
color: "#42a5f5"
image: assets/images/splash.png
次に、コマンドを実行します。
flutter pub get
flutter pub run flutter_native_splash:create
たったのこれだけです!
flutter_launcher_icons
アプリのランチャーアイコンを簡単に生成できるパッケージです。
ランチャーアイコンとはアプリのアイコンのことで、タップするとアプリが起動するアイコンなので launcher icon と呼ばれています。
このパッケージを使用すると、一度に複数の解像度のアイコンを生成でき、アンドロイドとiOSの両方で使用できます。
flutter_launcher_icons 使用例
pubspec.yaml
ファイルに flutter_launcher_icons
の設定を記述します
dev_dependencies:
flutter_launcher_icons: "^0.9.2"
次に、pubspec.yaml に flutter_icons セクションを追加して、ランチャーアイコンを設定します:
flutter_icons:
android: "launcher_icon"
ios: true
image_path: "assets/icon/icon.png"
image_path
で指定した画像がランチャーアイコンに設定されます。
次のコマンドを実行してランチャーアイコンを生成します:
flutter pub get
flutter pub run flutter_launcher_icons:main
これで、アプリのランチャーアイコンが指定した画像に置き換わります。
url_launcher
パッケージ名の通り、URL を起動するためのパッケージです。
標準のブラウザ、メールアプリ、電話アプリなどさまざまな形で URL を起動することができます。
主な使用例としては、ウェブサイトを開いたり、メールの送信画面を開いたりする際に使用します。
その他にもカスタム URL スキームを使用して、他のアプリケーションを起動することも可能です。
url_launcher 使用例
例えば、ウェブブラウザでウェブページを開くには、次のように launch
関数を使用します。
import 'package:url_launcher/url_launcher.dart';
void _launchURL() async {
const url = 'https://flutter.dev';
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
同様に、メールアプリを開くには、次のように mailto:
スキームを使います。
void _launchEmail() async {
const email = 'mailto:example@example.com';
if (await canLaunch(email)) {
await launch(email);
} else {
throw 'Could not launch $email';
}
}
これにより、宛先を example@example.com
に指定した状態でメールアプリが開きます。
upgrader
ユーザーが古いアプリを使用している場合に、アップデートを促してくれるパッケージです。
簡単な実装で以下のことをしてくれます。
- ダイアログを表示
- アップデートの内容を伝える
- アプリストアに遷移させる
upgrader 使用例
UpgradeAlert
を使用するだけで機能します。
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
title: 'Upgrader Example',
home: UpgradeAlert(
child: Scaffold(
appBar: AppBar(title: Text('Upgrader Example')),
body: Center(child: Text('Checking...')),
)),
);
}
}
in_app_review
アプリ内でユーザーにレビューを依頼できるパッケージです。
Android の In-App Review
と iOS の SKStoreReviewController
にアクセスするためのラッパーとなっています。
こちらの画像を見ていただくと想像しやすいと思います。
in_app_review 使用例
import 'package:in_app_review/in_app_review.dart';
final InAppReview inAppReview = InAppReview.instance;
if (await inAppReview.isAvailable()) {
inAppReview.requestReview();
}
以下の点からこの API を頻繁に使用することは推奨されていません。
- ポップアップが表示されなくなる
- ユーザーの体験が悪くなる
詳しくは下記をご覧ください。
webview_flutter
Android 及び iOS で WebView ウィジェットを提供するパッケージです。
WebView とはアプリ上にブラウザのような機能を持たせ、アプリ内で Web サイトを表示できるようにする機能のことです。
アプリから離脱せずに Web サイトを閲覧できるので UX が良いです!
webview_flutter 使用例
class WebViewExample extends StatefulWidget {
const WebViewExample({super.key});
State<WebViewExample> createState() => _WebViewExampleState();
}
class _WebViewExampleState extends State<WebViewExample> {
late final WebViewController controller;
void initState() {
super.initState();
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadRequest(Uri.parse('https://flutter.dev'));
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter Simple Example')),
body: WebViewWidget(controller: controller),
);
}
}
まとめ
今回は Flutter でよく使用される便利なパッケージをごく一部紹介しました。
Flutter ではまだまだたくさんのパッケージがあります。
全部を網羅することは不可能ですが、pub.dev
内を空文字で検索し、並び替えを MOST LIKES
に変更して上から見ていくと、よく使われている便利なパッケージがたくさん見つかって勉強になります。
以上です!
Discussion