<

HTML スロットを使用して Web でプラットフォーム ビューをレンダリングする

まとめ

Flutter は、すべての Web プラットフォーム ビューを DOM の一貫した場所にレンダリングするようになりました。 ~の直系の子供としてflt-glass-pane(レンダリング バックエンドに関係なく:htmlまたcanvaskit)。プラットフォーム ビューは次のようになります。「スロット付き」正しい方向に 標準の HTML 機能を使用したアプリの DOM の位置。

この変更が行われるまで、Flutter Web はレンダリングされたスタイルを変更していました。 プラットフォーム ビューのコンテンツを利用可能なスペースに合わせて配置/サイズ変更します。これ もうそうではありません。ユーザーはスペースをどのように利用したいかを決定できるようになりました フレームワークによってプラットフォーム ビューに割り当てられます。

コンテクスト

Flutter フレームワークは、ペイントを最適化するためにレンダー ツリーを頻繁に調整します。 最終的にフレームごとに行われる操作。 Web では、これらのレンダー ツリーは 多くの場合、変更により DOM 操作が発生します。

Flutter Web はプラットフォーム ビューのレンダリングに使用されます (HtmlElementViewウィジェット) DOM の対応する位置に直接コピーします。

特定の DOM 要素を一部の DOM 操作の「ターゲット」として使用すると、次のような問題が発生します。 要素は内部状態を失います。実際には、これは次のことを意味しますiframeタグはリロードされます、videoプレーヤーが再起動するか、編集可能なフォームが作成される可能性があります 編集内容が失われる可能性があります。

Flutter は、次を使用してプラットフォーム ビューをレンダリングするようになりました。スロット要素シングルの中に、 アプリ全体シャドウルート。スロット要素は追加/削除/移動できます。 基盤となるスロット付きコンテンツ (レンダリングされる) に影響を与えずに DOM をシャドウします。 一定の場所にあります)

この変更は以下に対して行われました。

  • Flutter Web のプラットフォーム ビューの動作を安定させます。
  • 両方のレンダリングでプラットフォーム ビューが Web でレンダリングされる方法を統一する バックエンド (htmlcanvaskit)。
  • DOM 内で予測可能な場所を提供することで、開発者は確実に CSS を使用してプラットフォーム ビューのスタイルを設定し、他の標準 DOM API を使用します。 そのような25d7d29f-347b-4e3d-86ab-ec84cbaf6ca、 とgetElementById

変更内容の説明

Flutter Web アプリは共通の内部でレンダリングされるようになりました。シャドウルートその中でスロット要素プラットフォームのビューを表します。実際の内容は、 各プラットフォーム ビューは次のようにレンダリングされます。前記シャドウルートの兄弟

...

<flt-glass-pane>
  ...
  <div id="platform-view">Contents</div> <!-- canvaskit -->
  <!-- OR -->
  <flt-platform-view>
    #shadow-root
    | <div id="platform-view">Contents</div> <!-- html -->
  </flt-platform-view>
  ...
</flt-glass-pane>

...

...

<flt-glass-pane>
  #shadow-root
  | ...
  | <flt-platform-view-slot>
  |   <slot name="platform-view-1" />
  | </flt-platform-view-slot>
  | ...
  <flt-platform-view slot="platform-view-1">
    <div id="platform-view">Contents</div>
  </flt-platform-view>
  ...
</flt-glass-pane>

...

この変更後、フレームワークが DOM ノードを移動する必要がある場合、 以上に動作しますflt-platform-view-slotのみを含む sslotエレメント。 スロットプロジェクトで定義されている内容flt-platform-view外側の要素 シャドウルート。flt-platform-view要素が DOM のターゲットになることはありません フレームワークからの操作を排除するため、リロードの問題が防止されます。

アプリの観点から見ると、この変更は透過的です。しかし、 これは とみなされる重大な変更一部のテストでは仮定が行われるため、 Flutter Webアプリの内部DOMについて、そして壊れます。

移行ガイド

コード

エンジンは、次のような警告メッセージをコンソールに出力する場合があります。

Height of Platform View type: [$viewType] may not be set. Defaulting to `height: 100%`.
Set `style.height` to any appropriate value to stop this message.

または:

Width of Platform View type: [$viewType] may not be set. Defaulting to `width: 100%`.
Set `style.width` to any appropriate value to stop this message.

以前は、によって返されたコンテンツは、PlatformViewFactory機能だった フレームワークによってサイズ変更および配置されます。代わりに、Flutter のサイズとサイズが変更されました。 ポジション<flt-platform-view-slot>、これはスロットの親です。 内容が投影されます。

上記の警告を停止するには、プラットフォーム ビューでstyle.widthstyle.heightルート要素を適切な (null 以外の) 値に変更します。

たとえば、ルートを作成するには、html.Element利用可能なスペースをすべて埋める フレームワークによって割り当てられた場合は、その値を設定しますstyle.widthstyle.heightプロパティ に'100%':

ui.platformViewRegistry.registerViewFactory(viewType, (int viewId) {
  final html.Element htmlElement = html.DivElement()
    // ..other props
    ..style.width = '100%'
    ..style.height = '100%';
  // ...
  return htmlElement;
});

プラットフォーム ビューのレイアウトに他のテクニックが使用されている場合 (たとえば、inset: 0) の値autoためにwidthheight警告を停止するには十分です。

について詳しく読むCSS widthCSS height

テスト

この変更後、ユーザーのテストコードは次のようになります。いいえを徹底的に検査する必要がある アプリのシャドウルートのコンテンツ。プラットフォーム ビューのコンテンツはすべて、 ~の直接の子として配置されるflt-glass-paneに包まれた、flt-platform-viewエレメント。

中を覗くのは避けてくださいflt-glass-paneシャドウ ルートとみなされます。「プライベート実装の詳細」、そのマークアップはいつでも変更される可能性があります。 無断で。

(上記の「移行」の例については、以下の関連する PR を参照してください)。

タイムライン

リリースされたバージョン: 2.3.0-16.0.pre
安定版リリース: 2.5

参考文献

設計書:

関連する問題:

  • 問題 #80524

関連する PR:

  • flutter/エンジン#25747: 機能を紹介します。
  • flutter/ flutter#82926: 微調整flutterテスト。
  • flutter/プラグイン#3964:微調整1b689b​​b7-7d8f-47f1-bcdd-40b5b27b1b62コード。
  • flutter/パッケージ#364:微調整packagesコード。