概要
FlutterはGoogleが開発したオープンソースのUIフレームワークであり、単一のコードベースから美しく高性能なモバイル、Web、デスクトップアプリケーションを構築できます。豊富なカスタマイズ可能なコンポーネントとハードウェアアクセラレーションによるグラフィックスを提供し、ネイティブのようなパフォーマンスを実現します。また、Flutterにはホットリロードなど、開発効率を向上させる機能も備わっています。
README プレビュー
\n \n \n \n \n \n \n\n\n[](https://flutter-dashboard.appspot.com/#/build?repo=flutter)\n[![Discord badge][]][Discord instructions]\n[![Twitter handle][]][Twitter badge]\n[![BlueSky badge][]][BlueSky handle]\n[](https://codecov.io/gh/flutter/flutter)\n[](https://insights.linuxfoundation.org/project/flutter)\n[](https://bestpractices.coreinfrastructure.org/projects/5631)\n[](https://slsa.dev)\n\nFlutter is Google's SDK for crafting beautiful, fast user experiences for\nmobile, web, and desktop from a single codebase. Flutter works with existing\ncode, is used by developers and organizations around the world, and is free and\nopen source.\n\n## Documentation\n\n* [Install Flutter](https://docs.flutter.dev/get-started)\n* [Flutter documentation](https://docs.flutter.dev)\n* [Development wiki](./docs/README.md)\n* [Contributing to Flutter](https://github.com/flutter/flutter/blob/main/CONTRIBUTING.md)\n\nFor release and other announcements, join the\n[flutter-announce](https://groups.google.com/g/flutter-announce)\nmailing list. Our documentation also tracks [breaking\nchanges](https://docs.flutter.dev/release/breaking-changes) across releases.\n\n## Terms of service\n\nThe Flutter tool may occasionally download resources from Google servers. By\ndownloading or using the Flutter SDK, you agree to the Google Terms of Service:\nhttps://policies.google.com/terms\n\nFor example, when installed from GitHub (as opposed to from a prepackaged\narchive), the Flutter tool will download the Dart SDK from Google servers\nimmediately when first run, as it is used to execute the `flutter` tool itself.\nThis will also occur when Flutter is upgraded (e.g. by running the `flutter\nupgrade` command).\n\n## About Flutter\n\nWe think Flutter will help you create beautiful, fast apps, with a productive,\nextensible and open development model, whether you're targeting iOS or Android,\nweb, Windows, macOS, Linux or embedding it as the UI toolkit for a platform of\nyour choice.
FAQ (5)
トラブル対応アニメーション中にピッカーが閉じられた際に、CupertinoPicker のタップ選択で発生する "StateError: Bad state: No element" クラッシュを修正する方法
これは、_CupertinoPickerState._handleChildTap における Flutter フレームワークの競合状態(flutter/flutter#192135)です。300ms のタップで選択するアニメーション(_kCupertinoPickerTapToScrollDuration)の後、ウィジェットがまだマウントされているかを確認せずに、コードが FixedExtentScrollController.selectedItem を読み取ります。中央から外れた位置へのタップから 300ms 以内にピッカーが破棄された場合(例:選択時に親がピッカーを非表示にする、または短い終了アニメーションを持つモーダルがポップされる場合)、selectedItem にはアタッチされたポジションがなく、Bad state: No element がスローされます。Flutter 3.27.0 から少なくとも 3.47.2 まで影響します。
修正が適用されるまでの回避策(PR flutter/packages#13012):
1. ピッカーがアニメーションより長く存続するよう破棄を遅延させる — 選択変更後、非表示/ポップする前に 300ms 以上待機します:
Timer(const Duration(milliseconds: 350), () {
if (mounted) Navigator.of(context).pop();
});注:
showCupertinoModalPopup のバリアのタップは、デフォルトでは安全です。その 335ms の終了トランジションが 300ms のアニメーションより長く存続するためです。
2. フレームワークにローカルでパッチを適用する — packages/flutter/lib/src/cupertino/picker.dart(または flutter/packages の cupertino_ui)内の await 後のコードをガードします:
await _effectiveController.animateToItem(
index,
duration: _kCupertinoPickerTapToScrollDuration,
curve: _kCupertinoPickerTapToScrollCurve,
);
if (!mounted) return; // add this guard
_enableHapticFeedback = true;
_lastHapticIndex = _effectiveController.selectedItem;
3. 最終手段として、PlatformDispatcher.instance.onError を介してエラーをグローバルにキャッチし、_handleChildTap からの StateError を無視します。
トラブル対応Flutter vector_mathでMatrix4のパースペクティブ変換(setEntry(3, 2, ...))がX/Y回転に適用されないのはなぜですか?
これはバグではなく、行列の想定された動作です。フラットなウィジェットはどこでも z = 0 となるため、最下行にパースペクティブ項があるだけでは w = 1 となり、除算するものがありません。また、setRotation() はパースペクティブを回転ブロックに折り込まずに、回転ブロックを置き換えてしまいます。動作する修正方法は2つあります:
1. まずパースペクティブを適用してから回転させます。これにより、回転がパースペクティブ項を w に折り込みます:
Matrix4.identity()
..setEntry(3, 2, 0.001)
..rotateX(x)
..rotateY(y);
2. Matrix4 を直接構築し、パースペクティブの強度を回転の第3列に掛け合わせます(Flutter チームにより動作確認済み):
return Matrix4(
r00, r10, r20, perspectiveStrength * r20,
r01, r11, r21, perspectiveStrength * r21,
r02, r12, r22, perspectiveStrength * r22,
xTranslation,
yTranslation,
zTranslation,
perspectiveStrength * zTranslation + 1,
);注意:
Matrix4.compose() や setEntry(3, 2, ...) の後に setRotation() を呼び出しても、X/Y 回転にパースペクティブは生成されないため、上記のいずれかの方法を使用してください。トラブル対応Flutter webでアクセシビリティ(semantics)を有効にするとTextFieldがフォーカスを失うのはなぜですか?また、どのように修正すればよいですか?
原因: 祖先の Theme が、以前のものと等しくならない ThemeData で再ビルドされると(例: build 内でインラインで WidgetStateProperty.resolveWith を作成している場合 — これには == のオーバーライドがありません)、ScrollableState.didChangeDependencies がスクロールポジションを再作成します。これによりセマンティクスのロールが scrollable と generic の間で入れ替わり(hasImplicitScrolling は position.haveDimensions が true になった場合にのみ設定されるため)、Web エンジンが DOM 要素を再追加し、document.activeElement が <body> に移動してしまうため、タイピングが <textarea> に届かなくなります。これは、TextField が SingleChildScrollView の内側にあり、何らかの再ビルドがトリガーされた場合(例: フォーカス/テキストリスナーからの setState)に発生します。
回避策: ThemeData を一度だけ構築し、毎回のビルドで同じインスタンスを再利用してください。build 内で構築するのではなく、final フィールド、initState、またはトップレベル/static 定数に保存してください。build 内でインラインで WidgetStateProperty.resolveWith(...) や == オーバーライドのないプロパティを割り当てることは避けてください。報告者による検証済み: ビルド間で 1 つの ThemeData オブジェクトを再利用するとタイピングが届くようになり、スクロールビューを取り除くことでも回避できます。これは確認済みの Flutter Web エンジン/フレームワークのバグ(ロールの入れ替わりによりフォーカスされたノードが移動する)であるため、修正が stable に入ったら Flutter もアップグレードしてください。
トラブル対応`flutter test --platform chrome` が "loading" のまま永遠にハングするのはなぜですか?また、どうすれば修正できますか?
これはFlutterのWebテストサーバーのバグです(Flutter 3.41.7で確認済み)。サーバーはリクエストに対して host.dart.js の部分文字列チェックでマッチングを行うため、ファイル名が host.dart で終わるライブラリ(例: foo_host.dart、ghost.dart)は foo_host.dart.js にコンパイルされ、これもマッチしてしまいます。サーバーは実際のモジュールの代わりにテストホストバンドルを返し、モジュールローダーが TypeError: Cannot read properties of undefined をスローし、ランナーはエラーもタイムアウトもなく、CPU使用率がほぼゼロのまま無期限に待機します。
修正方法:
1. Flutterをアップグレードする: このハングはFlutter 3.47.4 stableでは再現しません。flutter upgrade を実行し、その後 flutter test --platform chrome を再実行してください。
2. アップグレードできない場合の回避策: ライブラリファイルのベース名が host.dart で終わらないようにリネームし(例: foo_host.dart -> foo_host_api.dart)、すべてのインポートを更新してください。このようなスイートが1つあるだけでテスト実行全体が停止するため、プロジェクト内のすべてのライブラリファイルを確認してください。
診断のヒント: 停止したテストページをChrome DevToolsで開いてください。/<path>/foo_host.dart.js へのリクエストが /static/host.dart.js(約638 KBのdart2jsホストバンドル)とまったく同じバイト列を返す場合、このバグに遭遇しています。
トラブル対応なぜ長い Flutter Semantics ラベルが、Flutter web の iOS Safari 上で他のボタンへのタップを妨げるのですか?
これはFlutter webエンジンのバグです。不可視のsemanticsノードの長い折り返されたラベルが、その要素のボックスよりはるか下にはみ出し、Safariのネイティブなヒットテストに関与するため、視覚的に下にあるウィジェット(例:後のsliver内のボタン)をタップすると、上のsemanticノードがターゲットになり、代わりにそのコールバックが発火します。修正はPR #194011に含まれています。これを含むFlutterリリースにアップグレードしてください(Flutter 3.47.1で報告された時点ではまだレビュー中で、安定版リリースには含まれていなかったため、マイルストーンについてはPRを確認してください)。それまでは、再現環境で観察された緩和策として、Web上ではアクセシビリティラベルを短く保つ(折り返されないラベルはオーバーフローを回避します)、またはレイアウトを再構成します。個別のSliverToBoxAdapterをColumnに置き換えると、正しいスタッキング(z-index)とヒットテストが得られました。semanticsを無効にしても回避できますが、アクセシビリティが失われるため、実用的な回避策ではありません。