🆕

Flutter3.28.0で追加されそうなWidgetPreviewをサキドリ

2025/01/06に公開

この記事ではFlutterInProductionで紹介されたRoadmapのうちの
WidgetPreviewについて先取りして試してみた結果をお伝えいたします

WidgetPreviewはいつStableに入りそう?

正直正確なタイミングは分かりませんが
Preのバージョンのタグを見てみると3.28.0にはWidgetPreview用のコマンドがFlutterに追加されていることがわかります
https://github.com/flutter/flutter/releases/tag/3.28.0-0.0.pre

これだけだと3.28.0に確実に入るとは言えませんが、作業が始まりつつあることがわかります
さらに追ってみるとWidgetPreviewがどのようなアプローチで実現されるのかをなんとなく把握することができます

WidgetPreviewの実装について知りたい!


上記にもある、WidgetPreviewコマンド追加のPRを出しているのはbkonyiさんという方で
GitHubを追ってみるとDartとFlutterのTech leadであることがわかります

さらにGithubを追っていくと、WidgetPreviewについてのプロジェクトを発見しました
https://github.com/bkonyi/widget_preview

今回の記事では、そのプロジェクトにある情報を元にWidgetPreviewの機能を確認/予想して紹介いたします


WidgetPreviewの挙動と使い方

WidgetPreviewには独自のWidgetやアノテーションが必要になります

  • @Preview プレビューWidgetのListに付与するアノテーション
  • WidgetPreview プレビューしたいWidgetをWidgetPreviewでラップしプレビュー可能にするWidget

Previewの使い方

PreviewしたいWidgetを用意します
今回は例のため簡単なWidgetですが、もっと複雑なWidgetもプレビュー可能です

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

  
  Widget build(BuildContext context) => const Text('Hello World!');
}

次にプレビュー用の記述をします
lib以下のDartファイルで@Previewアノテーションを付与したList<WidgetPreview>を返り値となる関数を用意します

配列の中にはプレビューしたいWidgetをWidgetPreviewというWidgetでラップします
ちなみにWidgetPreviewウィジェットに各種設定をすることで、プレビューに変化を与えることができます(後述)

()
List<WidgetPreview> preview() => [
      const WidgetPreview(child: Text1(), name: 'Text1'),
    ];


WidgetPreviewでできること

まず単純にWidgetを表示し、動作を確認することができます
WidgetPreviewはシステム上でFlutterを動作させて表示をしているため、基本的にはWidgetの全ての機能を動作させることができます

  • TextField
  • Animation系Widget
  • Gestureを扱うタップ可能なWidget
  • ScrollableなWidget

これらはそのままプレビュー上でも動作します。なので単純な描画システムだけではなく
リッチな動作確認などもすることができます。

設定無しでできること

全てのプレビューで設定無しでできることとして拡大/縮小ができます。

ZoomIn ZoomOut Reset

それぞれのボタンはWidgetをzoomなどをすることができます

設定が必要な項目

また先述しましたが、プレビュー用のラッパーWidgetPreviewに各種プロパティを加えることで
様々な環境でのプレビューを行うことができます。
WidgetPreviewには上記のプロパティがあり、一つずつ紹介していきます

  • final String? name;
    プレビューの名前の設定をします

  • final Widget child;
    プレビューするWidgetを挿入します

  • final double? width; final double? height;
    プレビューするWidgetの最大サイズを決めます

  • final DeviceInfo? device;
    仮想で表示するデバイスのフレーム設定をすることができます
    platformなども指定でき詳細に設定すればiOS,Androidの特定機種などの指定も可能です
    Tablet,Phone,DesktopMonitor,Laptopなどの設定も可能です

      WidgetPreview(
        child: const Dashboard(),
        name: 'Dashboard on Android Phone',
        device: DeviceInfo.genericPhone(
          screenSize: const Size(360, 640),
          pixelRatio: 2.0,
          platform: TargetPlatform.android,
          id: 'android',
          name: 'Android Phone',
        ),
      ),

またdeviceが指定されている場合は

下記でも紹介しますがorientationを変更するRotateボタンが追加されます

  • final Orientation? orientation;
    deviceを指定した場合の方向を指定できます

  • final double? textScaleFactor;
    textScaleFactorを変更可能です
    基本的なOSには搭載されている文字サイズを大きくするオプションが設定されていた場合の状態をプレビューでも確かめることができます

  • final ThemeData? theme; final ThemeData? darkTheme;
    themeを設定することができます

また、themeのplatformにiosやandroidを指定することで
adaptiveなWidgetなどが、プラットフォームごとにどのように表示されるのかをテストすることができます。

またthemeが指定されている場合は、LightモードとDarkモードを変更するボタンが追加されます

  • final Brightness? platformBrightness;
    デフォルトのthemeモードを設定できます
platformBrightness: Brightness.light,

Darkモードをデフォルトで表示するなどの設定ができます


利用できそうなこと

機能を整理していての感想は、Previewという名前ではありますが
かなりリッチにWidgetの表示や動作をテストすることができます。

  • カタログアプリの代替

現在のplaybookwidgetbookのようなWidgetのCatalogとして利用されているものと遜色がなく、個人的にはPreviewを記述することでCatalogも同時に作れる世界線になったら嬉しいなと思いました。

  • VRTなどで実現している、textScalerなどの変更での表示テスト

textScalerが1以上の場合でのレイアウトの確認等は難しく、VRTなどで担保されていたものが開発中でも簡単に確認できるようになります。

  • コンポーネントベースの開発をシンプルに

コンポーネントを新規で作成する際は必要な引数等を適当に用意して開発を進めることがありますが
それらはPreview内で与え、API等のデータの用意が出来次第繋ぎこむなどの流れをより綺麗に割って作業することができそうです。

現在のFlutterへのWidgetPreview実装の進捗

現在(2025/1/6)のFlutterでのWidgetPreviewに関するPRを検索すると二件ヒットします

全体としてはまだ対応が必要ですが、着々と実装が進んでいます
また、アノテーション/Widgetの追加のPRを見ると、上記で紹介したプロパティの内のhight,width,textScalerについては実装がされていますが
それら以外は実装はされておらず、ファーストリリースでは入らない可能性がありそうでした。

WidgetPreviewをどのように実現しているのか

WidgetPreviewについて調べる内、構造についても理解が進みましたが
そちらは別記事にしてまとめさせていただきます🙇‍♂️

出典等資料

Discussion