🦔

【Flutter】何も表示させたくない時はContainerよりSizedBoxよりnilを使うと良い

2022/06/30に公開
2

はじめに

FlutterのUI作成中に...
「条件に応じて何も表示させたくないときあるねんな~,ホンマ」
ってみなさん思いますよね?

その時に Container()const SizedBox()を使用するのが一般的だと思います!

しかし const SizedBox() よりもさらなるパフォーマンスの向上を求めるなら nil を使用するのが良いのです!
今回はその nilパッケージ についてご紹介します!!

isVisible ? const Text('表示するでい') : const SizedBox(),

をこのように書くことができるんです。めっちゃ良い

isVisible ? const Text('表示するでい') : nil

nil ついて

https://pub.dev/packages/nil

nil とは

パフォーマンスへの影響は最小限である、何も表示しないときに追加するシンプルなウィジェット。

パフォーマンスへの影響が少ない理由

SizedBoxnil には以下の違いがあり,その違いから nil の方がパフォーマンスへの影響が少なくなります。

SizedBox

SizedBoxRenderObject を生成するため,画面上に何も描画しない場合でも,いくつかの計算が実行されてしまう。

nil

nilElement を作成するだけで RenderObject を作成しないウィジェットである。

Widget,Element, RenderObjectツリーについて

ツリー 役割
Widgetツリー UIの構成情報を保持する。
Elementツリー WidgetとRenderObjectの仲介役。
RenderObjectツリー UIのレイアウトと描画を行う。

RenderObjectElementについて詳しく知りたい方はこちらの記事が非常に参考になると思います!
https://blog.recruit.co.jp/rls/2019-12-24-flutter-rendering/
https://zenn.dev/kazutxt/books/flutter_practice_introduction/viewer/advanced_tree

使用例

サンプルのgif

pubspec.yaml
dependencies:
  nil: ^1.1.1

nilパッケージを追加しpub get

main.dart
import 'package:flutter/material.dart';
import 'package:nil/nil.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool isVisible = true;

  void toggle() {
    setState(() {
      isVisible = !isVisible;
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: isVisible ? const Text('表示するでい') : nil,
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: toggle,
      ),
    );
  }
}

パフォーマンスだけでなく書き方がシンプルになる方が個人的には良いとこかなとも思う!

注意

nilRowColumnなどの複数の子ウィジェットをもつchildren内での使用は意図されていないので、実行するとエラーが出てしまいます (パッケージのREADMEでも述べられています。)
そのためchildren内では下のように書くのが良いです。

Column(
        children: [
          isVisible ? const Text('表示するでい') : nil, //これはアウト。エラーが発生する
          if (isVisible) const Text('表示するでい'), // このように書くのが良い
        ],
      ),

さいごに

最後まで読んでいただきありがとうございました!
今回はnilについて知る機会があったんですけど,nilに関する記事がなかったため書いてみました!
参考になれば幸いです!

参考

https://zenn.dev/ymizushi/articles/ba6399a3a12711

Flutter大学

Discussion