Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Materialが消えた日 〜真っ白なFlutterキャンバスにRenderObjectで絵を描く〜

Materialが消えた日 〜真っ白なFlutterキャンバスにRenderObjectで絵を描く〜

Flutter Kaigi 2026 での登壇資料となります。

Avatar for Aoi Umigishi

Aoi Umigishi

October 29, 2026

More Decks by Aoi Umigishi

Other Decks in Programming

Transcript

  1. Materialが消えた日 / FlutterKaigi 2026 8月12日に何が起きたか Flutter 3.47 と同じ日に、 material_ui が

    1.0.0 に。 Today, we welcome the 1.0 release of the standalone material_ui and cupertino_ui packages. This is a major milestone that decouples design systems from the core SDK. — What's new in Flutter 3.47(2026-08-12) Material は、自分のバージョンを持つパッケージになりました。 https://flutter.dev/blog/whats-new-in-flutter-3-47 3
  2. Materialが消えた日 / FlutterKaigi 2026 でも、これは今日も動きます import 'package:flutter/material.dart'; material.dart git blob

    SHA @Deprecated の中身は、3.44.0 から今日の 3.47.8 まで同一です。 3.44.0 3.47.0 3.47.8 27dc1bc… 27dc1bc… 27dc1bc… 0件 0件 0件 gh api repos/flutter/flutter/contents/packages/flutter/lib/material.dart?ref={tag}(2026-10-26 実測) 4
  3. Materialが消えた日 / FlutterKaigi 2026 そして、もう beta に入っています // flutter/lib/material.dart(3.50 beta

    / 10月23日) @Deprecated( 'Use package:material_ui/material_ui.dart instead. ' 'This feature was deprecated after v3.47.0-0.0.pre.', ) library material; flutter create のひな形も、3.50 beta から material_ui に。 ※「削除」ではありません。削除は「来年」(#172942, 2026-10-03) https://github.com/flutter/flutter/pull/192957 / https://github.com/flutter/flutter/pull/192947 5
  4. Materialが消えた日 / FlutterKaigi 2026 つまり、今日は Material が deprecated になる、 直前のバージョン

    8/12 10/3 material_ui 1.0 非推奨が merge 引っ越し完了 beta に入る 10/29 11月頃 2027 今日 3.50 stable 削除 stable 3.47.8 見込み・非推奨に "next year" 6
  5. Materialが消えた日 / FlutterKaigi 2026 公式の説明は、一行 decoupling the Material and Cupertino

    design systems into standalone packages to accelerate development and allow them to evolve independently — Flutter & Dart's 2026 roadmap(2026-02-24) ……本当に、それだけでしょうか? https://flutter.dev/blog/flutter-darts-2026-roadmap 8
  6. Materialが消えた日 / FlutterKaigi 2026 2025年5月、あるプロジェクトが止まりました ... we are not actively

    developing Material 3 Expressive right now, and we will not be accepting contributions for these features at this time. — flutter/flutter#168813(2025-05-14 起票。文言は June 10, 2025 の Update より) Material 3 Expressive:Google I/O 2025 で発表された、Material の大型デザイン刷新。 https://github.com/flutter/flutter/issues/168813 9
  7. Materialが消えた日 / FlutterKaigi 2026 2つの刷新が、アーキテクチャ再検討のきっかけに The arrival of major updates

    for both Material and now Cupertino presents a significant (and exciting!) opportunity to apply past lessons and reconsider the long-term architecture ... — #168813 / Update: June 10, 2025 刷新を、アーキテクチャから考え直す機会と捉えた https://github.com/flutter/flutter/issues/168813 10
  8. Materialが消えた日 / FlutterKaigi 2026 4年越しのプロジェクト flutter/flutter#101479(2022年4月 起票・いまも open) フェーズ Reinforcement(補強)

    Relocation(引っ越し) Removal(撤去) https://github.com/flutter/flutter/issues/101479 内容 コアに土台を作る 新パッケージへ移す SDK から消す 状況 進行中 3.47 で完了 これから 11
  9. Materialが消えた日 / FlutterKaigi 2026 面白いのは「補強」のほう 外に出す前に、コア(widgets 層)へ「Material の見た目を外した部品」 を置いていた。 //

    3.44 で widgets 層に新規追加 showRawDialog(...) RawDialogRouteBuilder 既にあったもの: raw_tooltip / raw_menu_anchor / expansible / page_transitions_builder Raw 接頭辞 = 見た目を外した版 12
  10. Materialが消えた日 / FlutterKaigi 2026 目的地は、公式に書かれています We lay the groundwork for

    a style-neutral Flutter core widget catalog, making it easier to build custom design systems in the future. — What's new in Flutter 3.47 new, foundational, style-agnostic primitives ... un-opinionated "headless" widget — flutter/flutter#97496(補強フェーズ) https://flutter.dev/blog/whats-new-in-flutter-3-47 / https://github.com/flutter/flutter/issues/97496 13
  11. Materialが消えた日 / FlutterKaigi 2026 Material が、2つになりました SDK の中の Material material_ui

    この2つは、毎週ずれていきます 3.47.0 → 3.47.8 変化 0 1.0.0 → 1.8.0 159 コミット SDK: lib/src/material/ のツリーハッシュ一致 / material_ui: pub.dev・commits API(10/26 実測) 16
  12. Materialが消えた日 / FlutterKaigi 2026 実際、動いています 8/12 から約11週間で 10回 のリリース。 版

    日付 入ったもの 1.1.1 9/2 Slider の値ラベル:はみ出しを切る → 省略記号(既定の見た目) 1.5.0 9/28 Material 3 Expressive の IconButton(選んだ人だけ) 1.8.0 10/20 MaterialShapes (形のモーフィング) Flutter 公式ブログ: "work is already underway on official implementations of Liquid Glass and Material 3 Expressive" https://pub.dev/packages/material_ui/changelog / https://flutter.dev/blog/decoupling-material-cupertino 17
  13. Materialが消えた日 / FlutterKaigi 2026 届き方が、変わりました Flutter SDK 四半期ごと ━━━━▶ flutter

    upgrade ━━━━▶ あなたのアプリ material_ui 毎週 pub upgrade ━━━━▶ あなたのアプリ ━━━━▶ SDK を上げなくても、 pub upgrade だけで見た目が変わりうる 18
  14. Materialが消えた日 / FlutterKaigi 2026 ② の結論 移行は dart fix 一発で終わる。

    終わらないのは、 更新のたびに、見た目を確かめ続けること。 19
  15. Materialが消えた日 / FlutterKaigi 2026 Flutter の3つのツリーと RenderObject Widget 変更できない設定の集まり(設計図) Element

    Widget と RenderObject をつなぐ実体 RenderObject レイアウト・描画・ヒットテストを実際に行う ・ Row … 自分で RenderObject を作る 組み合わせて作った Widget … 自分では RenderObject を作らない(中の Widget に任せる) Padding 24
  16. Materialが消えた日 / FlutterKaigi 2026 RenderObject の書き方は、変わっていません の区間 3.44 → 3.47.0

    3.47.0 → 3.47.8 stable rendering/ 3.47.8 → 3.50 beta 変更 9ファイル(追加・削除 0) 0 大半は整形・不具合修正。 見た目が既定で変わるのは2件 複数行選択のハイライト幅/ソフトハイフン 今日書くメソッドのシグネチャ変更:0 (同じ期間に material_ui は 159 コミット) 25
  17. Materialが消えた日 / FlutterKaigi 2026 変わってほしくない部品だけ、自分で持つ アプリの顔になる部品 —— Material の更新で変わると困る 例:

    1.1.1(パッチ版)で Slider の値ラベルの見た目が変わった 持ち方 Material のコードを写す 組み合わせて合わせ込む RenderObject で計算する 文字が大きくなると なぜその数字か、分からないまま残る 決め打ちの高さのまま、変わらない 仕組みが分かり、追いかけて伸びる このあと:仕組みから見る = AI が書いた結果を判定する物差しになる 26
  18. Materialが消えた日 / FlutterKaigi 2026 見ていくのは、この3つ メソッド performLayout computeDistanceToActualBaseline hitTestSelf 決めること

    大きさと位置 文字の底線(ベースライン)を外へ伝える 押せる範囲 題材が ListTile なのは、Material 自身がこれを RenderBox 1個で書いていて、 最後に答え合わせができるから。 28
  19. Materialが消えた日 / FlutterKaigi 2026 ListTile と MyListTile:どこが違う? Material の ListTile

    Widget テーマなどで包み、中で本体を作る Flutter 標準 Element ( SlottedRenderObjectElement ) RenderObject 3行・右から左の言語にも対応 今日の MyListTile 4つの差し込み口を 直接持つ 同じクラス 2行だけを自分で計 算 ← 今日ここ 差し込み口の流れ:Widget の childForSlot → Element が子を作って insertRenderObjectChild → RenderObject の childForSlot で取り出して並べる 29
  20. Materialが消えた日 / FlutterKaigi 2026 出発点:数字で決め打ちした Tile 場所: RenderMyListTile › performLayout()

    (計算に変える前) // 高さとタイトルの位置を、数字で固定 const double tileHeight = 72.0; const double titleY = 14.0; _place(subtitle!, Offset(textStart, 41.5)); _place(title, Offset(textStart, titleY)); 普通の文字サイズでは、本物と揃う。 文字を2倍にすると、高さが変わらず、はみ出 す。 右図:上から 本物 ListTile / 既製品の合成 / 自作 RenderBox。左 ×1.0・右 ×2.0(Flutter 3.47.8 / Chrome) 30
  21. Materialが消えた日 / FlutterKaigi 2026 performLayout:大きさと位置を計算する 場所: RenderMyListTile › performLayout() の中の、高さと位置を決める部分

    // ① 底線が仕様の位置に来るよう、置き場所を計算 final double titleBaseline = title .getDistanceToBaseline(alphabetic, onlyReal: true) ?? titleHeight; final double targetTitleY = kTitleBaselineFromTop - titleBaseline; // ② 重なりそうなら、上下に引き離す(halfOverlap) // ③ 収まらなければ、高さのほうを伸ばす tileHeight = compact ? 2 * kMinVerticalPadding + titleHeight + subtitleHeight : kTargetTileHeight; size = constraints.constrain( Size(tileWidth, tileHeight)); 制約が降りてきて、大きさが上がる(constraints go down, sizes go up) 31
  22. Materialが消えた日 / FlutterKaigi 2026 ベースラインを、外へ伝える 場所: RenderMyListTile › computeDistanceToActualBaseline() @override

    double? computeDistanceToActualBaseline(TextBaseline baseline) { final double? d = title.getDistanceToActualBaseline(baseline); if (d == null) return null; return d + _offsetOf(title).dy; // title を置いた位置を足す } 隣の Tile や Row からの「この Tile の、文字の底線はどこ?」に答え る。 title が知っているのは自分の枠の上端から底線までだけ → Tile 全体の上端からの位置に直して返す。見 た目は変わらない 32
  23. Materialが消えた日 / FlutterKaigi 2026 Tile 全体を、押せるようにする 場所: RenderMyListTile › hitTestSelf()

    @override bool hitTestSelf(Offset position) => true; 「この場所のタップを、自分で受け取るか」に答える。 何も書かない → 受け取らない(アイコンや文字の上だけ) true → 文字のない余白も、この Tile が受け取る 見た目は変わらない(余白のタップは flutter test で確認)。GestureDetector なら使う側が毎回指定す る 33
  24. Materialが消えた日 / FlutterKaigi 2026 結果:文字を2倍にすると 本物 ListTile 自作 RenderBox 既製品の合成(高さ72に固定)

    高さ 128 125 72 ベースライン 60.4 58.7 64.7 はみ出し 追いかけるかどうか。ピクセル一致ではない 自作の Tile のレイアウトは material_ui に依存しない Flutter 3.47.8 / Chrome(Widget Preview と同じ Web 描画)で実測・2026-10-28 34
  25. Materialが消えた日 / FlutterKaigi 2026 Material も、同じ API で「計算」しています class _RenderListTile

    extends RenderBox with SlottedContainerRenderObjectMixin< _ListTileSlot, RenderBox> { @override void performLayout() { ... } @override void paint(...) { ... } @override bool hitTestSelf(Offset position) => true; @override double? computeDistanceToActualBaseline(...) } material_ui 1.8.0 の自前 RenderObject は33個。土台は全部コアの RenderBox 系。 material_ui 1.8.0 / lib/src/list_tile.dart(実質375行)— Copyright 2013 The Flutter Authors / BSD-3-Clause 36
  26. Materialが消えた日 / FlutterKaigi 2026 今日のまとめ Material は SDK の外へ。更新のたびに、見た目が変わりうる。 明日からできること

    1. material_ui に移行したら、 pub upgrade のたびに見た目を確かめる 2. 変わってほしくない部品を決めて、AI に Material に依存しない形で 書き直させる 3. 書き直したコードが、RenderObject の上で作成されたものか確か める 37
  27. Materialが消えた日 / FlutterKaigi 2026 改めまして Aoi Umigishi(東 優太) フリーランスの Flutter

    エンジニア(4年以上) FlutterKaigi 2024「SliverAppBarはなぜ変化する?」 38