9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Flutterの画面やWidgetをカタログ化できるWidgetbookを使ってみた

Last updated at Posted at 2022-06-25

Widgetbookとは?

Widgetbook公式

Widgetbookとは名前からも想像できるとおり、FlutterのWidgetをカタログのように確認することができるライブラリです。

以下のようにブラウザでSimulatorと同じ画面を確認したり、設定によっては各デバイスごとのレイアウトやテーマ別の見た目を簡単に確認することができます。
ホットリロードにも対応しているようですね。
スクリーン ショット 2022-06-25 に 20.37.19 午後.png

簡単なサンプルも作ってみたので気になる方はクローンして実際に動かして見て下さい。
https://github.com/Ryota-Nakamura-317/flutter_widgetbook_sample

手順

簡単に流れを説明します。

ライブラリの追加

dependencies:
  widgetbook: ^2.4.1

フォルダの追加

ルートにwidgetbookというフォルダを作成
スクリーン ショット 2022-06-25 に 19.27.43 午後.png

main.dartの作成

先程のwidgetbook配下にmain.dartを追加します。
devicesには結構いろんな種類のデバイスを予め選択することができます。

widgetbook/main.dart
import 'package:flutter/material.dart';
import 'package:widgetbook/widgetbook.dart';
import 'package:widgetbook_sample/theme.dart';

import 'components.dart';

void main() {
  runApp(
    const WidgetBookHotReload(),
  );
}

class WidgetBookHotReload extends StatelessWidget {
  const WidgetBookHotReload({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Widgetbook.material( // appInfo, themes, cateforiesがrequired
      appInfo: AppInfo(name: 'WidgetBook'),
      devices: const [ // ここでいろんなデバイスの指定が可能
        Apple.iPhone13Mini,
        Samsung.s21ultra,
        Desktop.desktop1080p,
      ],
      themes: [],
      categories: [],
    );
  }
}

これでセットアップ完了。

画面作成

widgetbookに反映させるために適当な画面を作成します。

lib/main.dart
import 'package:flutter/material.dart';
import 'package:widgetbook_sample/theme.dart';
import 'package:widgetbook_sample/widgets.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'WidgetBook',
      theme: lightTheme,
      darkTheme: darkTheme,
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('WidgetBook'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: const [
            CircleWidget(), // component
            SizedBox(height: 12),
            ButtonWidget(), // component
          ],
        ),
      ),
    );
  }
}

Widgetbookでテーマ切り替えの状態が確認できるように以下のようにテーマも定義しました。

theme.dart
import 'package:flutter/material.dart';

ThemeData get lightTheme {
  final base = ThemeData(
    colorScheme: const ColorScheme.light(),
    useMaterial3: true,
  );
  return base;
}

ThemeData get darkTheme {
  final base = ThemeData(
    colorScheme: const ColorScheme.dark(),
    useMaterial3: true,
  );
  return base;
}

componentは以下の簡単なWidgetを用意。

widgets.dart
import 'package:flutter/material.dart';

class CircleWidget extends StatelessWidget {
  const CircleWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 50,
      height: 50,
      decoration: const BoxDecoration(
        shape: BoxShape.circle,
        color: Colors.amber,
      ),
      child: const Center(child: Text('circle')),
    );
  }
}

class ButtonWidget extends StatelessWidget {
  const ButtonWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () {},
      child: const Text('button'),
    );
  }
}

出来上がった画面がこちら。
スクリーンショット 2022-06-25 20.56.47.png

Widgetbookに追加

では、これらをWidgetbookに反映させていきます。
先程のwidgetbook/main.dartにthemeとcategoryの追加をしました。

categoryはWidgetbookで左側のメニューにカテゴリとして表示されます。

スクリーン ショット 2022-06-25 に 21.01.04 午後.png
※↑赤いアイコンのところがカテゴリ

widgetbook/main.dart
class WidgetBookHotReload extends StatelessWidget {
  const WidgetBookHotReload({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Widgetbook.material(
      appInfo: AppInfo(name: 'WidgetBook'),
      devices: const [
        Apple.iPhone13Mini,
        Samsung.s21ultra,
        Desktop.desktop1080p,
      ],
      themes: [ // theme追加
        WidgetbookTheme(
          name: 'light',
          data: lightTheme,
        ),
        WidgetbookTheme(
          name: 'dark',
          data: darkTheme,
        ),
      ],
      categories: [ // category追加
        WidgetbookCategory(
          name: 'Screen',
          widgets: [
            screenComponent,
          ],
        ),
        WidgetbookCategory(
          name: 'Widgets',
          widgets: [
            widgetsComponent,
          ],
        ),
      ],
    );
  }
}

このあたりの運用はプロジェクトごとでやりやすいように決めるといいかもしれません。
categoriesにはWidgetbookCategoryを配列で定義し、WidgetbookCategory内のwidgetsにコンポーネントを渡します。以下コンポーネントです。

components.dart
import 'package:widgetbook/widgetbook.dart';
import 'package:widgetbook_sample/main.dart';
import 'package:widgetbook_sample/widgets.dart';

final screenComponent = WidgetbookComponent(
  name: 'screen',
  useCases: [
    WidgetbookUseCase(
      name: 'MyHomePage',
      builder: (_) => const MyHomePage(),
    ),
  ],
);

final widgetsComponent = WidgetbookComponent(
  name: 'widgets',
  useCases: [
    WidgetbookUseCase.center(
      name: 'Circle',
      child: const CircleWidget(),
    ),
    WidgetbookUseCase.center(
      name: 'Button',
      child: const ButtonWidget(),
    ),
  ],
);

WidgetBookComponentを定義しuseCasesWidgetbookUseCaseを配列で定義していきます。
WidgetbookUseCaseのbuilderに今回作成した画面を、WidgetbookUseCase.centerはwidgetbookで勝手に中心配置してくれるWidgetなのでこちらの場合はchildに切り出したWidgetを定義していきます。

さて、ここまでできたらwidgetbook/main.dartをビルドします。

widgetbook/main.dartをビルド

ビルドすると以下のような画面が立ち上がります。
左側には、WidgetbookCategory/WidgetbookComponent/WidgetbookUseCaseの順でディレクトリが表示されおり、
右側には、テーマの変更やデバイスの変更などがボタンひとつで操作できるパネルがあります。
スクリーンショット 2022-06-25 21.09.04.png

ボタン
スクリーンショット 2022-06-25 21.26.02.png

スクリーンショット 2022-06-25 21.25.59.png
画面
スクリーンショット 2022-06-25 21.25.50.png
こんな感じで左側ディレクトリをポチポチするだけで見た目がどんなものなのかを確認できます。
ダークモードもワンクリックで確認可能。
スクリーンショット 2022-06-25 21.27.53.png

さいごに

以上、Widgetbookの紹介でした。

導入により一手間増えますが、デザインの確認はとてもしやすくなるなと感じました。

参考

9
8
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
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?