Flutter パッケージのproviderの使い方を
下記のようなダークモード切り替え機能のtooltip
を作成しながら学びます。
providerの使い方のイメージがイマイチで
もっと応用してるコードを参考しながら学びたい、
ダークテーマ機能初めて作ると思う方におすすめです。
providerとは?
Google公式が提供するアプリケーションでの状態管理を簡単かつ効率的に行うためのパッケージ。
providerをインストール
flutter pub add provider
dependencies:
flutter:
sdk: flutter
provider: ^6.1.2 #2025/1/15時点の最新バージョン
providerの動きの図
+------------------------+ create +-----------------+ child +-----------------+
| ChangeNotifierProvider |---------->| ChangeModel |----------->| MyApp |
+------------------------+ +-----------------+ +-----------------+
^ | |
| | v
| notifyListeners() | +-----------------+
| | | Consumer |
| | +-----------------+
| | |
| | v
| | +-----------------+
| | | MyHomePage |
| | +-----------------+
| | |
| | Provider.of<ChangeModel>(context)
| +-----------------------------------------+
|
+-------------------------------------------------------------------------------+
onPressed: changeModelProvider.changeDarkmode()
コード全体
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// モデルを作成
class ChangeModel with ChangeNotifier {
bool _isDarkmodeFlag = false; // プライベート変数
bool get isDarkmodeFlag => _isDarkmodeFlag; // ゲッター
void changeDarkmode() {
_isDarkmodeFlag = !_isDarkmodeFlag; // ダークモードフラグを切り替え
notifyListeners(); // 変更をリスナーに通知してUIを更新
print(_isDarkmodeFlag);
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => ChangeModel(), // 提供するモデルを指定
child: MyApp(), // アプリ本体
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return Consumer<ChangeModel>(// Consumerを使って、ChangeModelの更新を監視
builder: (context, changeModelProvider, child) {
return MaterialApp(
title: 'Flutter Demo provider test',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.lime,
brightness: changeModelProvider.isDarkmodeFlag //フラグのbool値でテーマを指定する
? Brightness.dark
: Brightness.light,
),
useMaterial3: true,
),
home: const MyHomePage(),
);
});
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
//Provider.of<T>(context) は、context を起点にウィジェットツリーを遡り、T 型のオブジェクトを提供している Provider を探します。
final changeModelProvider = Provider.of<ChangeModel>(context); // インスタンスを取得
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Tooltip(
// toolchipを作成
message: 'Change brightness mode',
child: IconButton(
icon: Icon(
changeModelProvider.isDarkmodeFlag //フラグを使って表示するアイコンを変える
? Icons.brightness_2_outlined
: Icons.wb_sunny_outlined,
),
onPressed: () {
changeModelProvider.changeDarkmode(); // ダークモードを切り替え
},
),
),
Text("Hello World"),
],
),
),
);
}
}
主要コードを噛み砕く
パッケージをインポート
import 'package:provider/provider.dart';
モデルの作成 (ダークモードに切り替える内部の処理を作成)
・Flutterのfoundationパッケージに含まれるクラスChangeNotfier
を継承してモデルを作成
。
・モデルの中にフラグ変更処理のchangeDarkmode()
メソッドを作成
class ChangeModel with ChangeNotifier {
bool _isDarkFlag = false; //プライベート変数
bool get isDarkMode => _isDarkFlag; //ゲッタ-
void changeDarkmode() {
_isDarkFlag = !_isDarkFlag;
}
ConsumerでUIを更新
・Consumerウィジェット
を使って、ChangeModel
の変更を監視し、UIを更新できるようにする
・builder引数で、ChangeModelの値に基づいてUIを構築
する関数を指定してます。
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return Consumer<ChangeModel>( // Consumerを使って、ChangeModelの更新を監視
builder: (context, changeModelProvider, child) {
return MaterialApp(
// ...
);
});
}
}
テーマの切り替え
・colorSchemeウィジェットでflagの値でテーマを変えるよう指定
return MaterialApp(
title: 'Flutter Demo provider test',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.lime,
brightness: changeModelProvider.isDarkmodeFlag //フラグのbool値でテーマを指定する
? Brightness.dark
: Brightness.light,
),
useMaterial3: true,
),
home: const MyHomePage(),
);
});
}
tooltipを作成
・ChangeModelのインスタンスを取得
して、ダークモードのフラグ変更処理を実行できるようtoolchipeの押した後の処理(onPressed)に書く
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
//Provider.of<T>(context) は、context を起点にウィジェットツリーを遡り、T 型のオブジェクトを提供している Provider を探します。
final changeModelProvider =
Provider.of<ChangeModel>(context); // インスタンスを取得
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Tooltip(
// toolchipを作成
message: 'Change brightness mode',
child: IconButton(
icon: Icon(
changeModelProvider.isDarkmodeFlag //フラグを使って表示するアイコンを変える
? Icons.brightness_2_outlined
: Icons.wb_sunny_outlined,
),
onPressed: () {
changeModelProvider.changeDarkmode(); // ダークモードを切り替え
},
),
),
Text("Hello World"),
],
),
),
);
}
}
まとめ
今回は、providerパッケージを使ってダークモード切り替え機能を実装する方法を紹介しました。
providerは状態管理を簡単に行うことができるので、ぜひ活用してみてください。