🦁

single child scroll view下でのポジションの配置法

2024/02/08に公開

この記事では、スクロール可能ウィジェットにするのに必要なsingle child scroll viewについてとそれを用いた際に、親のサイズや制約に基づいて配置をするための方法を解説します。

私の例では、card widgetの子widgetの上にsingle child scroll viewを置いた所、card widgetの中央に子widgetが配置されませんでした。
それは、single child scroll viewが子であるcenterに無制限の高さを与えたために、期待された結果になりませんでした。


最初にsingle child scroll viewとbox constraints(制約)について解説します。

box constraints

  1. box constraintsとは何か?
    BoxConstraintsはFlutterのサイズ制約ロジックです。親から子へ渡される、幅の最大値・最小値と高さの最大値・最小値のことです。 Widgetは親に決められた最小値と最大値の間で、自身のSizeを決めることになります。

single child scroll view

A box in which a single widget can be scrolled.(子widgetをスクロール可能にするbox型のwidget)

  1. single child scroll viewの仕様について
    このwidgetは、子widgetに以下のbox constraintsを与えます。
    幅か高さスクロールする側の下限値を0、上限値を無制限(infinity)にする

具体例1:

Card(
    child: SingleChildScrollView(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Center(
          child: Text(),
        ),
      ),
    ),
),

この場合、center widgetに与えられたbox constarainsts(そのwidgetに与えられた最大サイズ)の高さは無制限になるため、centerは子ウィジェットの大きさに基づいてサイズを決めます。なのでcard widgetの大きさにならず、card widgetの中央にtextを配置することが出来なくなる。

解決法

解決法:SingleChildScrollViewの子に有限の制約を与える。
SingleChildScrollViewを使用しているので、子の高さ上限は無限になる。なので、下限をcardの表示域の高さに設定することにより、cardの表示域より小さくならないようにする事により問題を解決します。

Card(
  child: LayoutBuilder(builder: (context, constraints) {
    return SingleChildScrollView(
      child: ConstrainedBox(
        constraints:
        BoxConstraints(minHeight: constraints.maxHeight),
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Center(
            child: Text(),
          ),
        ),
      ),
    );
  }),
),

Cardの直下にLayoutBuilderを配置して、Cardが子に与えるconstraintsを取得します。それを下限の高さとしてConstrainedBoxで設定することで実現しています。

LayoutBuilderは、親のconstraintsを持ち、レイアウト時にbuild関数を呼び出す特徴を持っています。これは、親ウィジェットの制約に基づいて、子ウィジェットのサイズを動的に決定するために役立ちます。

参考記事

https://qiita.com/kikuchy/items/1c95e1a3b2300ff44d21
https://docs.flutter.dev/ui/layout/constraints

Discussion