🗂

Flutter|色々試したけどテキストに出る黄色い二重線が倒せない人へ

に公開

テキストに黄色い二重線が出る問題

Flutterにて、テキストの下に黄色い二重線(デバッグではない謎の装飾)が出て消えない問題の解消をしました。

メール変更画面 パスワード変更画面 タグ管理画面

「Flutter Text 黄色い二重線」等で調べるとScaffold/DefaultTextStyle が無い状況や、デバッグ用ベースライン表示debugPaintBaselinesEnabled というような情報が出てきます。それらの記事は一般的な外部記事は下部にまとめてありますので、まずはそれらを試してみましょう。

今回の事象は上記を試してもまだ表示されるしつこい黄色い二重線を倒すための記事になります。

本記事は主にFlutter初心者の方を対象としていますが、もし内容に誤りや改善点があれば、ぜひご指摘ください。

症状

  • テキストの下に黄色い二重線が引かれる。
  • flutter analyze ではエラーが出ない。
  • デバッグ用ベースライン表示(debugPaintBaselinesEnabled)を OFF にしても消えない。

よくある原因(別物)

外部記事がカバーする典型例の詳細です。これらで直るなら本記事は不要です。

DefaultTextStyle/Scaffold 不在

親に Material/Scaffold がなく DefaultTextStyle を拾えず警告線が出るケース。

デバッグベースライン表示

debugPaintBaselinesEnabled = true で黄色線が描かれるだけ。設定を切れば消える。

オーバーフロー警告

OVERFLOW の赤黒ストライプや黄色波線。ログに出るので判別しやすい。

今回の原因

TextStyle.height(行間)や strutStyle をカスタムした結果、親レイアウトが期待するラインメトリクスと食い違い、描画系が黄色い線を出していました。

このような事象が出やすい文脈は下記だと思われます。
・Cupertino系(CupertinoPageScaffold など)で高さ付きスタイルを直適用。
・Scroll直下の Text(ListView、SingleChildScrollView 配下)に高さ付きスタイルを当てる。
・Material と Cupertino が混在し、デフォルト行間が異なるところに高さ付きスタイルを入れる。

実例

メール変更画面 パスワード変更画面 タグ管理画面

適用していたスタイル

プロジェクト独自定義の TextStyleheight: 1.4 を含む)を Text ウィジェットに直接適用

何が食い違ったか

・Cupertino 系の親ウィジェット(CupertinoPageScaffold)は、デフォルトで height 未指定(= null)のテキストスタイルを期待している
・しかし子の Text に height: 1.4 を含むカスタムスタイルを直適用したため、親が想定する行間メトリクスと実際の描画高さが食い違った
・この不一致により、Flutter の描画エンジンが「期待と異なる高さ」を検出し、黄色い二重線(警告マーカー)を表示

結果

黄色い二重線が出現

対照例(問題なし)

同じ画面の本文テキストは CupertinoTheme.of(context).textTheme.textStyle.copyWith(fontSize: ...) を使用。height を指定していないため、親の期待する行間メトリクスと一致し、黄色線は出なかった

問題が出た実装

const headerLabelStyle = TextStyle(
  fontSize: 14,
  fontWeight: FontWeight.w600,
  height: 1.4, // 親(CupertinoPageScaffold)が想定しない行間
);

return CupertinoPageScaffold(
  navigationBar: CupertinoNavigationBar(
    trailing: Row(
      mainAxisSize: MainAxisSize.min,
      children: const [
        Text('タグ追加', style: headerLabelStyle),
        SizedBox(width: 12),
        Text('最新取得', style: headerLabelStyle),
      ],
    ),
  ),
  child: Container(),
);

解消

親コンテキストの行間に揃えて食い違いを無くす

  • 親コンテキスト(Cupertino/Material)のデフォルト行間に揃えて、親子のラインメトリクス食い違いをなくす
  • 行間を明示的に指定したい場合:TextStyle.height と同じ値を strutStyle にも設定するか、親子で同じテーマスタイルを共有してメトリクスを一致させる(=同じ高さを一意に使う)
  • height を付けない(必要なら height: null でリセット)

対応後(親の行間に合わせる)

// A: 親テーマの行間に揃える(height を付けない)
final headerLabelStyle = CupertinoTheme.of(context).textTheme.textStyle.copyWith(
  fontSize: 14,
  fontWeight: FontWeight.w600,
);

// B: 行間を明示したい場合は strutStyle も同じ値にそろえる
const headerLabelTight = TextStyle(
  fontSize: 14,
  fontWeight: FontWeight.w600,
  height: 1.2,
);
const headerLabelStrut = StrutStyle(height: 1.2, leading: 0);

return CupertinoPageScaffold(
  navigationBar: CupertinoNavigationBar(
    trailing: Row(
      mainAxisSize: MainAxisSize.min,
      children: const [
        Text('タグ追加', style: headerLabelTight, strutStyle: headerLabelStrut),
        SizedBox(width: 12),
        Text('最新取得', style: headerLabelTight, strutStyle: headerLabelStrut),
      ],
    ),
  ),
  child: Container(),
);

黄色い二重線が消えない時の対応策まとめ

  • デバッグベースライン表示は OFF か?
    • main.dartdebugPaintBaselinesEnabled = false を確認する
  • 親に Scaffold / Material / DefaultTextStyle はあるか?
    • Text の親階層にいずれかが存在することを確認する
  • 親のデフォルト行間に揃えているか?
    • 親のデフォルトスタイル(CupertinoTheme.of(context).textTheme.textStyle / Theme.of(context).textTheme.bodyMedium)を .copyWith() で使い、独自スタイルに height を付けない
  • レイアウト制約(ListView/Column/Stack)と食い違っていないか?
    • 親の想定行間に合わせたスタイルを適用する。必要なら DefaultTextStyle で親側を統一する
    • height を付けない、または height: null でリセットする。行間を明示する場合は strutStyle も同じ値に合わせる
  • 不要な装飾が付いていないか?
    • decoration: TextDecoration.none で不要な下線を無効化する
  • Material コンテキストを挟んだか?
    • 必要に応じて Material(color: Colors.transparent, child: Text(...)) で Material コンテキストを挟む

参考記事

Discussion