- アプリ開発
Flutter 3.35 で導入された Flutter Widget Previewer の紹介

2025年8月14日頃に公開された Flutter 3.35 から同梱された Flutter Widget Previewer を触ってみての使い所をご紹介します。
公式ドキュメントはこちら
概要
ブラウザ(Chrome)上で編集中のコードのウィジェットがリアルタイムでレンダリングされて表示内容の確認ができます。
Flutter 3.35 以上がインストールされていて利用可能状態になっていれば追加のパッケージ導入は不要です。
従来のホットリロードとの違い
VSCodeなど統合環境下ではアプリの実行中のホットリロード機能による随時更新・確認もできて便利ではあるのですが、以下の2点がネックになります。
- ウィジェット表示に至るまでの画面遷移の実装が何らか必要
- アプリの起動前の時点でコンパイルエラーがあるとビルドができない
Flutter Widget Previewer ではこれらの制限を受けないため手軽にUIの確認を行うことができ、UIの実装に専念ができる環境であると思います。
表示のための追加コード
1:コンストラクタ、factoryメソッドの確認
プレビュー対象とするウィジェットは以下の条件を満たす必要があります。
- 引数なしの public なコンストラクタまたは factoryメソッドが呼び出せること
2:トップレベル関数の設置
以下の条件を満たす関数を作成します。作成したウィジェットクラスと同じソースファイルに書くのがわかりやすいかと思います。
- トップレベル関数
- _ から始まらない関数名(=非privateであること)
例(https://docs.flutter.dev/tools/widget-previewer から引用)
import 'package:flutter/widget_previews.dart';
import 'package:flutter/material.dart'; // For Material widgets
@Preview(name: 'My Sample Text')
Widget mySampleText() {
return const Text('Hello, World!');
}
気をつけなければいけない点
Flutter Widget Previewer にも制限があり、気をつけないといけない点もあります。
https://docs.flutter.dev/tools/widget-previewer#restrictions-and-limitations
Google Chromeが必要
現時点で Chrome のインストールが必要です
動的なデータアクセスに制限
Flutter Web ベースで構築されているため、dart:io はサポートされません。dart:io に含まれているネイティブリソース(ファイルIOやHTTPなどのネットワークアクセス)のコードが含まれている場面では例外が発生します。
そのため、UIの表示のためのコードとロジックのコードやクラスが「適切に分離・疎結合になっていること」が大事なポイントとなります。(Flutter Widget Previewer の制限回避に限らず、ソフトウェア品質上でも大事なポイントでもあります)
例えば、画面の初期化時やボタンクリック時のタイミングで WebAPI を実行して外部からデータを取得することがあるかと思いますが、WebAPIを実行するコードのままではFlutter Widget Previewer上で確認ができないので、抽象化してDIしてあげると良い感じになります。
サンプルコード
Flutter 標準の StatefulWidget を使用した例です。他の状態管理ライブラリでも考え方は同じかと思います。
今回はDIコンテナやフレームワークを用いないコンストラクタインジェクションを適用しました。
import 'package:flutter/material.dart';
import 'package:flutter/widget_previews.dart';
import 'package:http/http.dart' as http;
// データ取得ロジック
/// データ取得機能を抽象化
abstract interface class DataClient {
Future<String> fetch();
}
/// モックデータを返す実装
class MockDataClient implements DataClient {
@override
Future<String> fetch() async {
await Future.delayed(const Duration(seconds: 2));
return 'モックデータです';
}
}
/// HTTPでデータを取得する実装
class HttpDataClient implements DataClient {
@override
Future<String> fetch() async {
final url = Uri.parse('https://example.com');
final response = await http.get(url, headers: {'Accept': 'text/plain'});
return response.body;
}
}
// UI部分
class MainPage extends StatefulWidget {
// 今回はコンストラクタインジェクションを用いた DataClient の差し替え
// 指定無しの場合は MockDataClient を使用
MainPage({super.key, DataClient? client})
: client = client ?? MockDataClient();
final DataClient client;
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
_MainPageState();
late Future<String> future = () async {
return widget.client.fetch();
}();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: future,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return const Center(child: CircularProgressIndicator());
case ConnectionState.active:
case ConnectionState.done:
return snapshot.hasError
? Center(child: Text('Error'))
: Center(child: Text(snapshot.data ?? 'No data'));
}
},
),
);
}
}
// Flutter Widget Preview 用のプレビュー関数
@Preview()
Widget mainPagePreview() {
// 引数を指定しないことで MockDataClient を使用をする
return MainPage();
}
結局 Flutter Widget Previewer は良さそう?
以下の点で個人的には「良さそう」と感じています。
- UIの実装に専念できる
- 表示確認までの画面遷移の実装や操作が不要
- 今回のような動的なデータを扱う場合などロジックと表示を分離・疎結合がはじめから意識できる
ドコドア エンジニア部
このブログでは、アプリ開発の現場で培ったフロントエンド、バックエンド、インフラ構築の知識から生成AI活用のノウハウまで、実践的な情報をアプリ開発に悩む皆様へ向けて発信しています!
【主な技術スタック】 Flutter / Firebase / Svelte / AWS / GCP / OpenAI API
