🐈

Flutterで大きさが可変な子要素に合わせて親要素の大きさを変更する

に公開

背景

大きさが可変な子要素に合わせてデザイン通りに実装するには、親要素の大きさを調整する必要がありました。
親要素の大きさに合わせるためにはFittedBoxを使う方法がよく紹介されていますが、
子要素の大きさに親要素を合わせる方法については情報が少なかったため、同様の課題に直面した際の参考としてまとめます。


結論

下記のコードを使うことで解決しました。

Row(
  children: [
    // 子要素が小さいときは何もない範囲を作るためにExpandedしておく
    Expanded(
      child: Row(
        children: [
          // 可変な要素の大きさに合わせてタップ判定範囲を変更する
          Flexible(
            child: IntrinsicWidth(
              child: HogeButton(), // 大きさが可変な子要素
            ),
          ),
        ],
      ),
    ),
    // 他の要素
  ],
),

解説

IntrinsicWidthとは

Rowchildrenのように子要素が複数あり、その中でwidthが指定されているものと指定されていないものがあるとき、指定されていない要素のwidthを指定されている要素のうちで最大のwidthに合わせてくれます。

IntrinsicWidth(
  child: Column(
    children: [
      SizedBox(
        height: 50,
        width: 100,
      ),
      SizedBox(
        height: 50,
      ),
      SizedBox(
        height: 50,
        width: 150,
      ),
    ],
  ),
),

上記のコードの場合、二つ目のSizedBoxwidthは150に調整されます。

そして、IntrinsicWidthの子要素が単体の時はその子要素の最小幅を計算してくれます。
下記のコードだと、HogeButtonの最小幅を計算しています。

IntrinsicWidth(
  child: HogeButton(), // 大きさが可変な子要素
),

FlexibleとExpandedを組み合わせている理由

まず、Flexibleを使うのはIntrinsicWidthが導き出したHogeButtonの最小幅に合わせて要素の大きさを調整するためです。
HogeButtonの最小幅が利用可能な幅(以下、親要素とする)より小さい時は最小幅を採用する、最小幅が親要素より大きい場合は親要素の幅を採用する、という具合です。

次に、Expandedを使うのは、HogeButtonの最小幅が親要素より小さい時に、他のRowの要素との間に何もない空間を作るためです。

最後に

ボタンのタップ範囲等、UXに関わる箇所はしっかりとこだわった実装が必要になるかと思います。
とはいえ、可読性の低いコードを書くのもあまり好ましくないと思います。
もっと簡潔なコードで目的を達成できないか、考えていきたいです。

Aprender Tech Blog

Discussion