お久しぶりです。みやかわです。
最近 Flutter をお勉強中です。
いい感じに作って完成!やったぜ!という日が続いていますが、やはり一度はちゃんと作ってAppストアなりに公開したいものです。
そうなると、バグをなくすためにテストやら維持をするためにアドセンス、効率よく作るにはどうすればよいか等々を考える必要があります。
今回は効率よく作る一つのものとして Flutter で使えるUIカタログについて書いていきます。
FlutterのUIカタログで有名所は widgetbook 、 storybook_flutter、 monarch、playbook かと思います。
今回は widgetbook について使い方を書いていきます。
[affi id=1]
widget book とは
widgetbook.io が作っている UIコンポーネントの管理ツールです。
TwitterでFluterのUIカタログについて検索をかけると使っている人がおおいようです。
公式がYoutubeで使い方を発信しているので大変わかりやすいです。
早速試す
サンプルの用意
今回使うものは以下のリポジトリに入れてあります。
はじめは以下のような構成にします。
% tree my_sample_widget_book/lib
my_sample_widget_book/lib
├── app.dart
├── main.dart
├── pages
│ └── main_page
│ └── main_page.dart
└── widgets
├── my_card
│ └── my_card.dart
└── my_text
└── my_text.dart
これを起動すると以下のようになります。
widgetbookのインストール
いつものようにライブラリをインストールコマンドを叩きます。
flutter pub add widgetbook --dev
1.0.2 が入りました。
## pubspec.yaml
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^1.0.0
widgetbook: ^1.0.2
UIカタログを作る
プロジェクトのルートに widgetbook というフォルダを作成し、main.dart を作成します。
widgetbook/main.dart にUIカタログを作っていきます。
※ フォルダ名はテキトーで良いです。ここでは widgetbook というフォルダを作ります。
% tree widgetbook
widgetbook
└── main.dart
最初に空のUIカタログを作ります。
以下のコードを widgetbook/main.dartにコピペします。
import 'package:flutter/material.dart';
import 'package:widgetbook/widgetbook.dart';
class WidgetbookhotReload extends StatelessWidget {
const WidgetbookhotReload({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Widgetbook(
categories: const [], appInfo: AppInfo(name: 'Recipe App')); // name がUIカタログの題名
}
}
void main() {
runApp(const WidgetbookhotReload());
}
その後、 widgetbook/main.dart を起動します。
flutter run -t widgetbook/main.dart -d chrome
コマンドを実行すると、Chromeが立ち上がり、UIカタログが表示されます。
自作したWidgetをUIカタログに乗せる
では、作成したWidgetをUIカタログに表示します。
以下のコードをコピペ
import 'package:flutter/material.dart';
import 'package:my_sample_widget_book/pages/main_page/main_page.dart';
import 'package:my_sample_widget_book/widgets/my_card/my_card.dart';
import 'package:my_sample_widget_book/widgets/my_text/my_text.dart';
import 'package:widgetbook/widgetbook.dart';
class WidgetbookhotReload extends StatelessWidget {
const WidgetbookhotReload({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Widgetbook(
appInfo: AppInfo(name: 'Recipe App'),
lightTheme: ThemeData.light(),
darkTheme: ThemeData.dark(),
categories: [
// widgets 関連
WidgetbookCategory(
name: 'widgets',
widgets: [
// MyCard の UIカタログ
WidgetbookWidget(name: 'MyCard', useCases: [
WidgetbookUseCase(
name: 'Default',
builder: (context) => const MyCard(),
)
]),
// MyText の UIカタログ
WidgetbookWidget(name: 'MyText', useCases: [
WidgetbookUseCase(
name: 'Test1',
builder: (context) => const MyText(param: 'test'),
),
WidgetbookUseCase(
name: 'Test2',
builder: (context) => const MyText(param: 'hoge'),
)
]),
],
),
// Pages 関連
WidgetbookCategory(name: 'Pages', widgets: [
// MainPage の UIカタログ
WidgetbookWidget(name: 'mainPage', useCases: [
WidgetbookUseCase(
name: 'Default', builder: (context) => const MainPage())
])
])
],
);
}
}
void main() {
runApp(const WidgetbookhotReload());
}
実行すると、以下のように自作したwidgetが表示されます。
もっとかんたんにUIカタログを作りたい
先程の解説でUIカタログを作ることができました。
しかしながら、Widgetを作るたびに widgetbook/main.dart を更新する必要が出てきます。
正直めんどいですよね。
ということで、widgetbook/main.dart 相当のものを自動で生成してくれる方法があります。
簡単に作ることができるライブラリのインストール
flutter pub add widgetbook_annotation --dev
flutter pub add widgetbook_generator --dev
flutter pub add build_runner --dev
インストール後の pubspec.yaml
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^1.0.0
widgetbook: ^1.0.2
widgetbook_generator: ^1.0.2
widgetbook_annotation: ^1.0.0
build_runner: ^2.1.5
実装してみる
はじめに、widgetbookの大枠を作っていきます。
lib/main.dart を以下のように編集。
ポイントは @WidgetbookTheme と @WidgetbookApp です。
@WidgetbookTheme で テーマを設定し、 @WidgetbookApp で表示するレイアウトを定義しています。
import 'package:flutter/material.dart';
import 'package:my_sample_widget_book/app.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart';
// テーマ設定
@WidgetbookTheme.dark()
ThemeData darkTheme() => ThemeData.dark();
@WidgetbookTheme.light()
ThemeData lightTheme() => ThemeData.light();
// UIカタログの名前と出漁するデバイス設定
@WidgetbookApp(name: 'Recipe App', devices: [Apple.iPhone12, Samsung.s21ultra])
void main() {
runApp(const App());
}
次は widget ごとにUIカタログを定義します。
MyText() を例にすると以下のような感じです。
MyText の Widget があるフォルダに my_test_widgetbook.dart を作成。
% tree lib/widgets/
lib/widgets/
├── my_card
│ └── my_card.dart
└── my_text
├── my_test_widgetbook.dart
└── my_text.dart
※ my_test.widgetbook.dart のように my_test と widgetbook の間をピリオドにすると自動生成しないので注意。
そして lib/widgets/my_test_widgetbook.dart に以下をコピペ
import 'package:flutter/material.dart';
import 'package:my_sample_widget_book/widgets/my_text/my_text.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart';
@WidgetbookUseCase(name: 'Test1', type: MyText) // ユースケース名
Widget myTestUseCase1(BuildContext context) {
return const MyText(param: 'test');
}
@WidgetbookUseCase(name: 'Test2', type: MyText)
Widget myTestUseCase2(BuildContext context) {
return const MyText(param: 'hoge');
}
これで MyTest widget の UIカタログの準備は完了です。
MyCard Widget と MainPage についても同様のことをしていきます。
作ったものは github に上がっています。
作成後し終えたら、早速生成していきます。
ビルドランナーを走らせてコードを自動生成します。
% flutter pub run build_runner build
[INFO] Generating build script...
[INFO] Generating build script completed, took 355ms
[INFO] Precompiling build script......
[INFO] Precompiling build script... completed, took 5.0s
[INFO] Initializing inputs
[INFO] Building new asset graph...
[INFO] Building new asset graph completed, took 504ms
[INFO] Checking for unexpected pre-existing outputs....
[INFO] Checking for unexpected pre-existing outputs. completed, took 1ms
[INFO] Running build...
[INFO] Generating SDK summary...
[INFO] 2.9s elapsed, 0/8 actions completed.
[INFO] Generating SDK summary completed, took 2.9s
[INFO] 4.0s elapsed, 0/8 actions completed.
[INFO] 5.1s elapsed, 0/8 actions completed.
[INFO] 6.1s elapsed, 0/8 actions completed.
[INFO] 11.3s elapsed, 0/8 actions completed.
[INFO] Running build completed, took 11.7s
[INFO] Caching finalized dependency graph...
[INFO] Caching finalized dependency graph completed, took 36ms
[INFO] Succeeded after 11.8s with 5 outputs (24 actions)
成功すると、 lib フォルダに main.widgetbook.dart というファイルが生成されます。
こいつを開くと UIカタログが表示されます。
% flutter run -t lib/main.widgetbook.dart -d chrome
どうやらフォルダ階層に合わせてUIカタログも振り分けられるらしいようです。
ちょっとアクセスしづらい。。。
ともあれ、これで自動でUIカタログを作ることができました。
まとめ
数あるUIカタログの中で今回はwidgetbookを使ったUIカタログの方法を書いてみました。
自動でUIカタログが生成されるのはホント楽で良いです。
また今回は詳細な設定については省きました。細かくチューニングしたいという人は公式を参照してください。
それでは今度は playbookかstorybook-flutter についても書こうと思います。