2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Flutter】初学者が意外と陥りやすいTextウィジェットの黄色い下線問題

Last updated at Posted at 2024-01-21

はじめに

通常、Flutter開発においてTextウィジェットはScaffold内で使用されることが多いです。

以下の場合、テキストは正常に表示され、特に問題はありません。

main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        body: Center(
          child: Text('text'),
        ),
      ),
    );
  }
}

次に、Scaffoldがない場合のコード例を見てみましょう。

main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Center(
        child: Text('text'),
      ),
    );
  }
}

するとテキストが異常に大きく、赤文字で黄色い下線が表示されるという、エラーを連想させるような表示になります。

解決方法

① Materialを使用(シンプル)

child: Material(
  child: Text('text'),
),

② DefaultTextStyleを使用

child: DefaultTextStyle(
  style: TextStyle(decoration: TextDecoration.none),
  child: Text('text'),
),

③ Scaffoldを使用

割愛します。

原因

この問題は、TextウィジェットがScaffoldのWidgetツリー内にないために発生します。

ではなぜ、Scaffoldの有無でスタイルが変わるのでしょうか?

公式にも書かれていますがTextウィジェットは何もスタイルを指定しない場合、一番近いDefaultTextStyleを利用します。

The style argument is optional. When omitted, the text will use the style from the closest enclosing DefaultTextStyle.

これは、Scaffoldで囲われていない場合、TextウィジェットはMaterialAppのDefaultTextStyleを利用することを意味します。

以下MaterialAppのコードの抜粋です。
_errorTextStyleがDefaultTextStyleとして使用されていることがわかります。

app.dart
/// [MaterialApp] uses this [TextStyle] as its [DefaultTextStyle] to encourage
/// developers to be intentional about their [DefaultTextStyle].
///
/// In Material Design, most [Text] widgets are contained in [Material] widgets,
/// which sets a specific [DefaultTextStyle]. If you're seeing text that uses
/// this text style, consider putting your text in a [Material] widget (or
/// another widget that sets a [DefaultTextStyle]).
const TextStyle _errorTextStyle = TextStyle(
  color: Color(0xD0FF0000),
  fontFamily: 'monospace',
  fontSize: 48.0,
  fontWeight: FontWeight.w900,
  decoration: TextDecoration.underline,
  decorationColor: Color(0xFFFFFF00),
  decorationStyle: TextDecorationStyle.double,
  debugLabel: 'fallback style; consider putting your text in a Material',
);

このコードから、Scaffoldで作られるDefaultTextStyleではなく、MaterialAppで作られるDefaultTextStyleがTextウィジェットに適用されることがわかりました。

事例

しかし、特定のシナリオではTextウィジェットをScaffoldの外で使用する必要がある場合があるかもしれません。これには以下のような状況が含まれます。

  • 非同期処理後のダイアログ表示
    データ取得などの非同期処理が完了した後に表示されるダイアログ内でTextウィジェットを使用する場合。

  • ローディング画面の表示
    データの読み込みを開始する際にローディング画面を表示し、その中で「読み込み中...」などのメッセージをTextウィジェットで表示する場合。

他のシナリオも考えられますが、このような例では、ScaffoldのWidgetツリー外に配置される場合がありますので、注意して実装していきたいです。

参考

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?