Flutter:Textの上に余白があるのに上寄せできない
結論:「TextStyle」に「height」プロパティを1.0で設定する
2022/7/10 Flutter エラー・バグ日記
下図のように、Container内にTextを配置したところ、明らかに上に余白があるので、上寄せしたかったが、なかなか実現できず、苦しむ。

この状態のコードは以下のとおり。
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
color: Colors.yellow,
width: 100,
height: 30,
),
Container(
color: Colors.green,
width: 100,
height: 18,
child: Text(
"テストテスト",
style: TextStyle(fontSize: 15.0),
),
),
Container(
color: Colors.orange,
width: 100,
height: 30,
),
],
),
真ん中のContainer(緑色)の高さは18.0、テキストのフォントサイズは15.0なので、縦幅には収まっているはず。。
ひたすら調べて出てきた情報をもとに、以下のことを試したが、いずれも機能せず。
- 親Containerに「alignment: Alignment.topLeft」を設定
→ 変化せず - Textを「Align」でラップし、「alignment: Alignment.topLeft」を設定
→ 変化せず - Textを「Column」でラップし、「MainAxisAlignment.start」を設定
→ overflowエラーが発生 - Textを「Padding」でラップし、bottomだけ設定
→ テキストの下部が隠れてしまう - Containerに「margin」をbottomだけ設定
→ 下のColumn要素(オレンジ)との間が空いてしまう
Cardウィジェットは、デフォルトでmarginが設定されているが、Containerには無いはず、、、と思いつつ、念のためPaddingやmarginを試したが、やはり関係なかった。
また、Textには「textAlign」というプロパティがあるが、これは横方向の位置を決めるだけなので、今回の目的(上寄せ)には合わず。
DevToolを見ると分かるかもしれない、と思って確認すると、TextとContainerのいずれも高さが18.0になっていた。

親ウィジェット(Container)のサイズまで広がるのは理解できるが、なぜ上だけ余白ができるのか、分からない。。手がかりを得られず。。
ここで、試しにフォントサイズを思いっきり小さくしてみたところ、実は「Alignment.topLeft」が機能していたと分かった。

ここで初めてフォントサイズが絡む「TextStyle」の問題だと気づく。
調べてみると、下記の記事を発見。まさにこれでした(ありがとうございます!)。
Textウェジェット自体に、デフォルトで一定の高さが設定されてしまうとは。。。(baselineが影響するかも、ということは頭をよぎっていたけど、それ以上、TextStyleに踏み込んで調査できていなかった)
リンク先の公式ページも確認し、内容を理解。
結果、「TextStyle」に「height」プロパティを1.0で設定することで、上寄せを実現できた。

なお、1.0より小さくすると、上にはみ出す。
また、上下中央にしたいときは、Containerとフォントのサイズに応じて、1.0より大きい数値でちょうど良い値を探せば設定できた。
以下に、最終的なコード全文を掲載(参考として、前述した解決に至らなかったコードもコメントアウトで掲載)。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Test",
theme: ThemeData.light(),
home: SampleScreen(),
);
}
}
class SampleScreen extends StatefulWidget {
@override
_SampleScreenState createState() => _SampleScreenState();
}
class _SampleScreenState extends State<SampleScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
color: Colors.yellow,
width: 100,
height: 30,
),
Container(
color: Colors.green,
width: 100,
height: 18,
// ↓元々の状態
// child: Text(
// "テストテスト",
// style: TextStyle(fontSize: 15.0),
// ),
// ↓(1)追加しても変化なし
// alignment: Alignment.topLeft,
// ↓(2)Alignでラップしても変化なし
// child: Align(
// alignment: Alignment.topLeft,
// child: Text(
// "テストテスト",
// style: TextStyle(fontSize: 15.0),
// ),
// ),
// ↓(3)ColumnとmainAxisAlignmentでラップするとオーバーフローエラー
// child: Column(
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// Text(
// "テストテスト",
// style: TextStyle(fontSize: 15.0),
// ),
// ],
// ),
// ↓(4)下部にPaddingを設定すると、下部が隠れてしまう
// child: Padding(
// padding: const EdgeInsets.only(bottom: 3.0),
// child: Text(
// "テストテスト",
// style: TextStyle(fontSize: 15.0),
// ),
// ),
// ↓(6)下部にmarginを設定すると、次のColumn要素との間が空くだけ
// margin: EdgeInsets.only(bottom: 3.0),
// ↓(7)これで解決!
child: Text(
"テストテスト",
style: TextStyle(
// ↓これを追加 ※上寄せは1.0。上下中央にしたいときは1.2ぐらい(Containerとフォントのサイズによる)
height: 1.0,
fontSize: 15.0,
),
),
),
Container(
color: Colors.orange,
width: 100,
height: 30,
),
],
),
),
);
}
}
\一般的なエラー対処法をまとめた記事はこちら/
リリースしたアプリ(全てFlutterで開発)
個人アプリ開発で役立ったもの
おすすめの学習教材
\超初心者向けでオススメな元Udemyの講座/
\キャンペーン時を狙えば安価で網羅的な内容が学べる(日本語訳あり)/
\Gitの基礎について無料で学べる/
おすすめの学習書籍
\実用的。image_pickerに関してかなり助けられた/
\Dartの基礎文法を素早くインプットできる/






