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には上のようなことが書かれていないので、実際にどうやったら位置関係を調整できるというのが、実装を調べるしかないというのがなんともいやらしい。
けど、調べることができるだけましなのかな。
コメント