Flutter-ListTile内要素の位置関係を調べてみた

ListTile内のLeading, Title, SubTile, Trailingのそれぞれの位置関係について調べてみた。

ポップアップメニューの要素としてListTileを入れようとしたのだけど、そのままだとMaterial Designのメニュー構成の仕様に合わなかったので、PopupMenuItemとchildにListTileを指定した場合、同パラメータを調整するべきなのかというところから始まった。

位置関係

大まかに表すと、以下の様な感じになる。


下段中の「パラメータの決定方法」と書かれている部分は、指定されたパラメータがnullの場合、→で示された順番でパラメータが決定されることを表している。

①leadingウィジェット

②titleウィジェット

③subtitleウィジェット

④trailingウィジェット

⑤contentPadding

ListTileの外側を覆うPadding要素。
パラメータは、直接指定→テーマ→デフォルトの順で決定されている。
デフォルトはEdgeInsets.symmetric(horizontal: 16.0)が使われる。

⑥titleまでの幅

leadingウィジェットがある場合は、以下の様な計算式で求める。ない場合は0。

  • max(leadingのサイズ, minLeadingWidth)+ horizontalTitleGap+ visualDensity.horizontal * 2.0

それぞれのパラメータの値は「直接指定→テーマ→デフォルト」。

minLeadingWidthのデフォルトは40、horizontalTitleGapは16となっている。

visualDensityは「直接指示→ListTileTheme→Thema」で、ListTileTheme のデフォルトはnull、Themeのデフォルト値は-2。

visualDensityの作用により、minLeadingWidth: 0, horizontalTitleGap: 0としてもtitleとleadingがピッタリということはなく、title側がleading側にめり込むような位置関係になる。

titleとleadingをぴったりさせるには、直接指定でvisualDensity.horizontalを0にする必要がある。

⑦ titleまでの幅

trailingがある場合は、以下の様な計算式で求める。ない場合は0。

  • max(trailingのサイズ+ horizontalTitleGap+ visualDensity.horizontal * 2.0, 32)

trailingのサイズがどんなに小さくても最低32は保つようになっている。

⑧ leadingのY位置

タイトル高さが72より大きい場合は16。

それ以外は以下の士気で求める。

  • min((タイトル高さ-leading高さ)/2, 16)つまり縦方向中心配置だけど、leadingの高さが小さい場合は16になるということ。

titleの高さよりleadingの高さの方が大きい場合、title高さに調整させられる。

⑨ trailingのY位置

タイトル高さが72より大きい場合は16。

それ以外は(タイトル高さ-trailing高さ)/2。

タイトル高さ

titleとsubtiltleウィジェットの合計高さ。

この最低高さは以下の表の値からvisualDensity.baseSizeAdjustment.dxを引いた値になっている。

Dense True False
1行表示 48 56
2行表示 64 72
3行以上表示 76 88

visualDensity.baseSizeAdjustmentは現在-8(verticalの値は-2)なので、1行の場合それぞれ40、48になる。

Leading, trailingの高さもタイトル部分のサイズに合わせて調整される。

ちなみに前項で「タイトル高さが72より大きい場合」と書かれているのは、上の表から計算した値を用いている。

「タイトル高さが72より大きい場合」は3行以上表示でDenseがFlaseの場合のみになる。

あと邪道だけどListTileの高さをかさ上げする場合、VisualDencityのvertilalを変更することで、4まで(実際は16)高くすることができる。

またtitleやsubtitleに指定されたTextにsytleの直接指示がない場合、テキストのスタイルは以下の様になる。

Material 2 Material 3
title(drawer) textTheme.bodyLarge textTheme.bodyMedium
title(list) textTheme.titleMedium
subtitle textTheme.bodyMedium

Denseがtrueの場合、titleのフォントサイズは13、subtitleのフォントサイズは12に強制変更される。

最後に

FlutterのAPIには上のようなことが書かれていないので、実際にどうやったら位置関係を調整できるというのが、実装を調べるしかないというのがなんともいやらしい。

けど、調べることができるだけましなのかな。

コメント

タイトルとURLをコピーしました