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の基礎文法を素早くインプットできる/