0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Flutter】Flutterのproviderを使ってダークモード切り替え機能を実装する

Posted at

Flutter パッケージのproviderの使い方を
下記のようなダークモード切り替え機能のtooltipを作成しながら学びます。

providerの使い方のイメージがイマイチで
もっと応用してるコードを参考しながら学びたい、
ダークテーマ機能初めて作ると思う方におすすめです。

2025-01-16-02-15-56.gif

providerとは?

Google公式が提供するアプリケーションでの状態管理を簡単かつ効率的に行うためのパッケージ。

providerをインストール

flutter pub add provider
pubspec.yaml
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は状態管理を簡単に行うことができるので、ぜひ活用してみてください。

参考資料

provider | Flutter Package
Flutter 公式ドキュメント - Provider

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?