[Flutter]widget管理の答え、見つけました。

2024 年 9 月 24 日 by sugakir

はじめに

今回はFlutterのwidget管理において、個人的にこれが答えだ!
と思うものを見つけたので、この技術について学習した内容を、
ハンズオン形式でお伝えします。

WidgetBook

もったいぶってすみません、その技術とは、「Widgetbook」のことです。
Widgetbook → Widgetbook (docs.page)
こちらのWidgetbookを使うことで、アプリ内で使用されているそれぞれの
widgetをカタログ形式で参照することができるライブラリです。

Widgetbookでできること

・実装したwidgetを視覚的に確認できる。
 基本的にコードベースで作成したものは、実行してみるまでその実態を
 確認できません。しかし、Widgetbookは、ツールを立ち上げるだけで
 全てのwidgetを表示することが出来ます。
 このメリットを活かして、お客様にデザインの確認を依頼することが
 出来たり、メンバ間でwidgetの共有が容易になったりします。

widgetを階層化して整理することができる。
 Widgetbookのカタログでは、閲覧するためのメニューがありますが、
 このメニュー内のwidgetをフォルダにまとめたり、整理することが
 出来るので、カラーごとに分けたり、種類ごとに分けたりと、集計や
 管理が容易になります。

・デバイス設定を反映させた見た目を確認できる。
 基本的にはブラウザでそのカタログを開くこととなるWidgetbookで
 あるが、カタログのBuilderでAddonのオプションを設定することで
 簡単にライトモード/ダークモードの見た目を確認できます。

実際に導入してみる

・プロジェクトのルートディレクトリで新しいプロジェクトを作成する
 プロジェクト名はとりあえず「widgetbook」としておく。

widgetbook/pubspec.yamlにライブラリを定義する

  widgetbook: ^3.8.1
  widgetbook_annotation: ^3.1.0

widgetbook/main.dartを以下のように定義する。

void main() {
  runApp(const WidgetbookApp());
}

@widgetbook.App()
class WidgetbookApp extends StatelessWidget {
  const WidgetbookApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Widgetbook.material(
      directories: directories,
    );
  }
}

[@widgetbook.App()]アノテーションで宣言したこの部分が、
カタログのBuilderとなります。

次にカタログに追加するwidgetの宣言です。
仮に、以下のボタンがプロジェクトで使用されているとします。

import 'package:flutter/material.dart';

class CancelButton extends StatelessWidget{
  const CancelButton({super.key});

  @override
  Widget build(BuildContext context) {
    return const IconButton(
      onPressed: null, 
      icon: Icon(
        Icons.cancel, 
        color: Colors.redAccent
      ),
    );
  }
}

このwidgetをwidgetbookプロジェクト内で参照し、
カタログ化に必要な設定を施します。

import 'package:flutter/material.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook;

import 'package:entry_app/cancel_button.dart';

import 'main.dart';

@widgetbook.UseCase(
  name: 'CancelButton',
  type: CancelButton,
  path: '[widgets]/buttons'
)
Widget buildCancelButtonUseCase(BuildContext context) {
  return buildCatalogUseCase(
    CancelButton(),
    'CancelButton'
  );
}

コード中の[@widgetbook.UseCase]の部分に設定します。
nameに名前を、typeは型なので、widgetの宣言時の命名で良いです。
最後にパスですが、ここは任意パラメータなので設定しない
人も多いですが、ここに〇〇/〇〇と書くことで、カタログを階層化
することが出来るため、widgetの整理がしやすくなります。

ここまで終わったら、以下のコマンドを実行し、
不変なデータクラスの生成と、Buildを行います。

fvm flutter pub run build_runner build --delete-conflicting-outputs

実際に動かしてみる

デバッグで確認します。デバイスをChromeに設定しておきましょう。

表示できました。注目すべきは左側のエクスプローラの部分です。
わかりやすいように他のwidgetも追加しておきました。
画像のように、階層化することで、widgetごとに整理されるため、
視覚的に分類がわかりやすくなっています。

こちらのカタログでは、初期表示の見た目だけでなく、
ボタンホバーの挙動やボタンクリック時の挙動も確認できます。
(事前に設定しておく必要あり)

まとめ

今回ご紹介したのはWidgetbookというデザイン管理ツールです。
今まではモックや設計書でお客様に確認いただいていたものも、
実際のwidgetと全く同じもので確認できるため、意思疎通が計り
やすいです。また、プロジェクト内でwidgetが追加された時に、
このWidgetbook用のファイルひとつ追加するだけで、カタログに
追加できるので、今までドキュメントで管理していた場合などは、
メンテナンスの必要がなくなり、保守性も高いです。
Flutterエンジニアでも使いこなしている人ばかりではないため、
このような一工夫をすることで、技術力のアピールにもなります。
Flutterを使った案件で、ぜひ実践してみてはいかがでしょうか?

タグ:

TrackBack