MediumのManaging visibility in Flutterという記事で、FlutterでVisibilityを制御するためのカスタムWidget、その名もVisibility
が紹介されてます。
このVisibility Widgetを作ってしまえば、色々なところで再利用できて便利ですね。
上記のカスタムVisibility widgetでは子widgetに対して以下4つの可視性を設定できます。
- Visible
- 普通に見えている状態
- Invisible
- 見えてはいないけど、領域は確保されている状態
- Offcreen
- 画面上に領域は無いけれどもWidget自体は生成されていて、サイズ情報などは取得できる状態
- Gone
- 見えていないし、領域も確保されておらずサイズもない状態
Offscreen
は、例えばアニメーションの最後に使われるWidgetで、そのタイミングまでは見えないし領域も確保したく無いけれど、事前にサイズだけは取得したいという時などに便利だそうです。
ただ注意点として、最初の状態で見えないWidgetは、そもそもWidgetTreeに含めない方が良いと筆者は言っています。
プラクティスとしては以下の感じです。
List<Widget> views = [];
if (shouldBeIncluded) {
views.add(myView);
}
// use views later
また、
Opacity widgets can be super expensive so use Invisible sparingly
とも筆者は言っています。
ここの文脈がちょっと私にはよく分からないのですが、単にOpacity
widgetを使って可視性を制御するよりは、筆者が紹介しているVisibility widgetのInvisibleを使う方が(レンダリングコスト的に)まだマシということでしょうか。
(Visibility widgetを使ったInvisible時にも、以下のようにIgnorePointer
widgetの子widgetにOpacity
が使われているので、少し混乱しています。)
下記のように、invisibleの場合はOpacity
ウィジェットを使って不可視にしているのですが、この**Opacity
はコストがかかるので、invisibileは控えめに使ってね**、と言っています。
(@sankentou さん、ご指摘ありがとうございました。)
else if (visibility == VisibilityFlag.invisible) {
return new IgnorePointer(
ignoring: true,
child: new Opacity(
opacity: 0.0,
child: child,
),
);
}