【Flutter】Textのレイアウト適用方法を徹底解説【サンプルコードあり】

こんにちはyu_to(@yu_to_python)です。

Flutterではアプリ内にテキストを表示させるのにTextというWidgetを使用します。

今回はこのTextに様々なレイアウトを適用する方法を徹底解説していきます。

そもそもWidgetの事について詳しく知らないという方はこちらの記事で詳しく解説しているので参考にしてください。

【Flutter】UI構築する際の基本Widgetついて解説!【サンプルコードあり】

 

この記事を最後まで読めばTextの使い方、よく使うプロパティについて理解できると思うので是非最後まで読んでみてください。

Textの特徴

アプリに文字を表示できる

その名の通りアプリ内に文字を表示させる事が可能です。それ以上でもそれ以下でもないです。

Flutterでは画面にテキストを表示する用のWidgetがTextとRichTextの2つ用意されています。

Textは単一の文字列を画面表示する際に使用します。

一方RichTextは文字の途中途中で区切って別のスタイルを適用させたりとリッチな文字を作成する際に使用します。

サンプルコード

コピペですぐ動かせるのでまずは実際に動かしてみてください。

動作確認したバージョンは下記の通りです。

  • Flutter 3.0.1
  • Dart 2.13.3
pubspec.yaml
...
dependencies:
  flutter:
    sdk: flutter
  google_fonts: 2.2.0 // ←バージョンはキャロット記号なしで指定する。
...
main.dart
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'demo',
      home: Home(),
    );
  }
}

class Home extends StatelessWidget {
  const Home({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Text')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // とりあえずテキストを表示させたいだけ
            Text('Text'),
            // テキストのフォントカラーを設定
            Text('color', style: TextStyle(color: Colors.red)),
            // テキストのフォントスタイルを設定
            Text('fontStyle', style: TextStyle(fontStyle: FontStyle.italic)),
            // テキストの太さを設定
            Text('fontWeight', style: TextStyle(fontWeight: FontWeight.bold)),
            // テキストの背景色を設定
            Text(
              'backgroundColor',
              style: TextStyle(backgroundColor: Colors.red),
            ),
            // テキストのフォントサイズを設定
            Text('fontSize', style: TextStyle(fontSize: 36)),
            // テキストの間隔を設定
            Text('letterSpacing', style: TextStyle(letterSpacing: 5)),
            // 単語の間隔を設定
            Text('word Spacing', style: TextStyle(wordSpacing: 100)),
            // テキストの高さを設定
            Text('height', style: TextStyle(height: 5)),
            // 上線を設定
            Text(
              'decoration: TextDecoration.overline',
              style: TextStyle(
                  decoration: TextDecoration.overline,
                  decorationColor: Colors.red,
                  decorationStyle: TextDecorationStyle.solid),
            ),
            // 中央線を設定
            Text(
              'decoration: TextDecoration.lineThrough',
              style: TextStyle(
                  decoration: TextDecoration.lineThrough,
                  decorationColor: Colors.red,
                  decorationStyle: TextDecorationStyle.solid),
            ),
            // 下線を設定
            Text(
              'decoration: TextDecoration.underline',
              style: TextStyle(
                  decoration: TextDecoration.underline,
                  decorationColor: Colors.red,
                  decorationStyle: TextDecorationStyle.solid),
            ),

            // テキストのフォントを変えるにはライブラリを使う
            Text(
              "GoogleFonts",
              // フォントをdotGothic16に指定
              style: GoogleFonts.dotGothic16(
                textStyle: TextStyle(fontSize: 50),
              ),
            ),

            RichText(
              text: TextSpan(
                style: TextStyle(color: Colors.black),
                children: [
                  TextSpan(
                    text: '部分的に',
                    style: TextStyle(
                      color: Colors.red,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  TextSpan(
                    text: 'スタイルを変えれるのが',
                    style: TextStyle(
                      color: Colors.green,
                      fontStyle: FontStyle.italic,
                    ),
                  ),
                  TextSpan(
                    text: ' RichText ',
                    style: GoogleFonts.acme(
                      textStyle: TextStyle(
                        color: Colors.blue,
                        fontSize: 30,
                      ),
                    ),
                  ),
                  TextSpan(
                    style: TextStyle(
                      color: Colors.orange,
                    ),
                    text: 'なのです!',
                  ),
                ],
              ),
            ),

            SizedBox(
              width: double.infinity,
              child: Text(
                'TextAlign.left',
                textAlign: TextAlign.left,
              ),
            ),
            SizedBox(
              width: double.infinity,
              child: Text(
                'TextAlign.center',
                textAlign: TextAlign.center,
              ),
            ),
            SizedBox(
              width: double.infinity,
              child: Text(
                'TextAlign.right',
                textAlign: TextAlign.right,
              ),
            ),

            Text(
              'デフォルトだと折り返されるーーーーーーーーーーーーーーーーーーーーーーーーーーーーー',
            ),
            Text(
              'softWrap: falseをつけると折り返さないーーーーーーーーーーーーーーーーーーーーーー',
              softWrap: false,
            ),
            Text(
              'TextOverflow.clipをつけると画面幅っぱいで表示されるーーーーーーーーーーーー',
              softWrap: false,
              overflow: TextOverflow.clip,
            ),
            Text(
              'TextOverflow.fadeをつけるとclipと同じ+末尾が透過するーーーーーーーーーーーーーー',
              softWrap: false,
              overflow: TextOverflow.fade,
            ),
            Text(
              'TextOverflow.visibleをつけると画面幅に関係なく表示するーーーーーーーーーーーーーー',
              softWrap: false,
              overflow: TextOverflow.visible,
            ),
            Text(
              'TextOverflow.ellipsisをつけると超えた分が「...」で表示されるーーーーーーーーーー',
              softWrap: false,
              overflow: TextOverflow.ellipsis,
            ),
            Text(
              'maxLinesをつけると複数行で表示されるーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー',
              maxLines: 2,
            ),

            DefaultTextStyle(
              style: TextStyle(
                color: Colors.red,
                fontSize: 20,
              ),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: <Widget>[
                  Text('DefaultTextStyle'),
                  Text('でラップしたTextは'),
                  Text('全て同じスタイルになる'),
                  DefaultTextStyle(
                    style: TextStyle(
                      color: Colors.green,
                      fontSize: 20,
                    ),
                    child: Text('DefaultTextStyleは上書き可能'),
                  )
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

ビルドするとこんな感じになります。

よく使うプロパティ

style

テキストの様々なスタイルを設定できるプロパティです。

TextStyleを指定してその中でテキストの太さ、スタイル、サイズ、フォントカラー等を設定します。

TextStyleで用意されているプロパティで良く使うものとしては下記があります。

color

テキストの色

color
...
// テキストのフォントカラーを設定
Text('color', style: TextStyle(color: Colors.red)),
...

fontStyle

テキストの書式

fontStyle
...
// テキストのフォントスタイルを設定
Text('fontStyle', style: TextStyle(fontStyle: FontStyle.italic)),
...

fontWeight

テキストの太さ

fontWeight
...
// テキストの太さを設定
Text('fontWeight', style: TextStyle(fontWeight: FontWeight.bold)),
...

backgroundColor

テキストの背景色

backgroundColor
...
// テキストの背景色を設定
Text(
  'backgroundColor',
  style: TextStyle(backgroundColor: Colors.red),
),
...

fontSize

フォントの大きさ

letterSpacing
...
// テキストの間隔を設定
Text('letterSpacing', style: TextStyle(letterSpacing: 5)),
...

letterSpacing

テキストの間隔

letterSpacing
...
// テキストの間隔を設定
Text('letterSpacing', style: TextStyle(letterSpacing: 5)),
...

wordSpacing

単語の間隔

wordSpacing
...
// 単語の間隔を設定
Text('word Spacing', style: TextStyle(wordSpacing: 100)),
...

height

テキストの高さ

height
...
Text('Text'),
// テキストの高さを設定
Text('height', style: TextStyle(height: 5)),
...

decoration

テキストに下線や取り消し線をつけれる。

TextDecorationを指定して3通りの線を表示できる。

overline上線
lineThrough中央線(取り消し線)
underline下線

また、上記のdecorationプロパティを使う場合decorationStyleプロパティ線のスタイルも設定が必須になる。

TextDecorationStyleを指定して下記5通りのスタイルを選択します。

solid単独線
double二重線
dotted点線
dashed破線
wavy波線

線の色はdecorationColorプロパティで設定できる。(指定方法はcolorプロパティと同じ)

decoration
...
// 上線を設定
Text(
  'decoration: TextDecoration.overline',
  style: TextStyle(
      decoration: TextDecoration.overline,
      decorationColor: Colors.red,
      decorationStyle: TextDecorationStyle.solid),
),
// 中央線を設定
Text(
  'decoration: TextDecoration.lineThrough',
  style: TextStyle(
      decoration: TextDecoration.lineThrough,
      decorationColor: Colors.red,
      decorationStyle: TextDecorationStyle.solid),
),
// 下線を設定
Text(
  'decoration: TextDecoration.underline',
  style: TextStyle(
      decoration: TextDecoration.underline,
      decorationColor: Colors.red,
      decorationStyle: TextDecorationStyle.solid),
),
...

softWrap

テキストを折り返すかを設定できるプロパティ。

デフォルトだと画面幅を超えるテキストを表示させる場合折り返して表示されますが、softWrap:falseをつけると折り返さずに表示できます。

softWrap
...
Text(
  'デフォルトだと折り返されるーーーーーーーーーーーーーーーーーーーーーーーーーーーーー',
),
Text(
  'softWrap: falseをつけると折り返さないーーーーーーーーーーーーーーーーーーーーーー',
  softWrap: false,
),
...

overflow

テキストを折り返さない時に見切れたテキストの表示をどうするか設定するプロパティ。

テキストを折り返さない時なのでsoftWrapと一緒に使わないと効果がないので注意です。

overflow
...
Text(
  'TextOverflow.clipをつけると画面幅っぱいで表示されるーーーーーーーーーーーー',
  softWrap: false,
  overflow: TextOverflow.clip,
),
Text(
  'TextOverflow.fadeをつけるとclipと同じ+末尾が透過するーーーーーーーーーーーーーー',
  softWrap: false,
  overflow: TextOverflow.fade,
),
Text(
  'TextOverflow.visibleをつけると画面幅に関係なく表示するーーーーーーーーーーーーーー',
  softWrap: false,
  overflow: TextOverflow.visible,
),
Text(
  'TextOverflow.ellipsisをつけると超えた分が「...」で表示されるーーーーーーーーーー',
  softWrap: false,
  overflow: TextOverflow.ellipsis,
),
...

maxLines

表示させる最大行を設定するプロパティ。

こちらはsoftWrapと一緒に使うと効果が打ち消されてしまうので注意です。(maxLinesを設定しても一行になります。)

maxLines
...
Text(
  'maxLinesをつけると複数行で表示されるーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー',
  maxLines: 2,
)
...

textAlign

テキストの位置を設定できるプロパティ。

TextAlignを指定することで画面左寄り、画面中央、画面右寄りと指定できます。

注意点としてはTextまたはRichTextの周囲に可動域が設定されていないと位置を設定できないです。

サンプルコードの場合はTextの周囲に可動域を作るためにSizedBoxでラップしています。

SizedBoxについてはこちらの記事で個別に解説しているのでよければ参考にしてください。

【Flutter】Widgetのサイズを変更できるSizedBoxの使い方【サンプルコードあり】

 

textAlign
...
SizedBox(
  width: double.infinity,
  child: Text(
    'TextAlign.left',
    textAlign: TextAlign.left,
  ),
),
SizedBox(
  width: double.infinity,
  child: Text(
    'TextAlign.center',
    textAlign: TextAlign.center,
  ),
),
SizedBox(
  width: double.infinity,
  child: Text(
    'TextAlign.right',
    textAlign: TextAlign.right,
  ),
),
...

RichText

RichTextはテキストの一部のみスタイルを別にしたい時に便利なWidgetです。

TextSpanと一緒に使うことでHTMLのspanタグの様な使い方ができます。

TextSpanには先程紹介したTextと同じプロパティが使用できます。

RichText
...
RichText(
  text: TextSpan(  
    style: TextStyle(color: Colors.black),
    children: [
      TextSpan(
        text: '部分的に',
        style: TextStyle(
          color: Colors.red,
          fontWeight: FontWeight.bold,
        ),
      ),
      TextSpan(
        text: 'スタイルを変えれるのが',
        style: TextStyle(
          color: Colors.green,
          fontStyle: FontStyle.italic,
        ),
      ),
      TextSpan(
        text: ' RichText ',
        style: GoogleFonts.acme(
          textStyle: TextStyle(
            color: Colors.blue,
            fontSize: 30,
          ),
        ),
      ),
      TextSpan(
        style: TextStyle(
          color: Colors.orange,
        ),
        text: 'なのです!',
      ),
    ],
  ),
),
...

tips

テキストのフォントを変更したい時

サンプルコードでも触れていますが、TextやRichTextで表示させるテキストのフォントを変更したい時はGoogleフォントのライブラリをインポートすることで変更可能です。

具体的な変更のやり方はこちらで詳しく解説しているので良ければ参考にしてみてください。

【Flutter】アプリ内でGoogleフォントを適用させる方法を徹底解説!【サンプルコードあり】

 

コンパイル定数

コンパイル定数
...
// とりあえずテキストを表示させたいだけ
const Text('Text'),
...

Text,RichTextはこの様にconstをWidgetの頭に付けることでコンパイル時にそのWidgetをキャッシュしておくことができます。

つまり画面を再描画してもconstを付けたText、RichTextは再描画されずにキャッシュを再利用して描画するのでアプリのパフォーマンス向上に繋がります。

このconstはコンパイル時に状態を確定できるWidgetであればどれにでもつけることが可能です。

今回のサンプルコードでは画面再描画時でも状態が変わらないStatelessWidgetを使っているため付けていませんが、StatefulWidgetや他の状態管理ライブラリ等を使っている場合は積極的に使用するのがおすすめです。

RichTextはText.richで代用可能

RichTextはText.richでも同じ様な書き方ができます。

違いはTextSpanを指定する時textプロパティを使うか使わないかだけです。

記述やインデントを少しでも少なくしたいならText.richを使うといいでしょう。

RichText
...
RichText(
  text: TextSpan(  // ←で「text:」を使ってる
    children: [
      TextSpan(
        text: 'これが',
        style: TextStyle(
          color: Colors.red,
          fontWeight: FontWeight.bold,
        ),
      ),
      TextSpan(
        text: ' RichText ',
        style: GoogleFonts.acme(
          textStyle: TextStyle(
            color: Colors.blue,
            fontSize: 30,
          ),
        ),
      ),
    ],
  ),
),
...
Text.rich
...
Text.rich(
  TextSpan(  // ←で「text:」を使ってない
    children: [
      TextSpan(
        text: 'これが',
        style: TextStyle(
          color: Colors.red,
          fontWeight: FontWeight.bold,
        ),
      ),
      TextSpan(
        text: ' Text.rich ',
        style: GoogleFonts.acme(
          textStyle: TextStyle(
            color: Colors.blue,
            fontSize: 30,
          ),
        ),
      ),
    ],
  ),
),
...

DefaultTextStyleで子Textのスタイルを指定

DefaultTextStyleの入れ子になっているTextは何も指定しなくてもDefaultTextStyleで指定したスタイルと同じ様に適用されます。

DefaultTextStyleの中にDefaultTextStyleを入れた場合は上書きされて内側の方が優先されます。

<meta charset=”utf-8″>DefaultTextStyle
...
DefaultTextStyle(
  style: TextStyle(
    color: Colors.red,
    fontSize: 20,
  ),
  child: Column(
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    children: <Widget>[
      Text('DefaultTextStyle'),
      Text('でラップしたTextは'),
      Text('全て同じスタイルになる'),
      DefaultTextStyle(
        style: TextStyle(
          color: Colors.green,
          fontSize: 20,
        ),
        child: Text('DefaultTextStyleは上書き可能'),
      )
    ],
  ),
)
...

おわり

今回はTextについて解説してきました。

今回紹介した仕様やプロパティ以外も、もっと深堀りしたい方は公式ドキュメントを参照してみてください。

このブログでは他にもFlutterに関する記事を上げているので良ければそちらも参考にしてみてください。

質問やご指摘もお待ちしてますー。

【2022年最新】現役エンジニアがFlutter初学者向けおすすめ技術書3選を紹介!

 

【Flutter】GridViewでインスタグラム風UIを簡単作成【サンプルコード】

【BottomNavigationBar】フッターで画面切り替えする方法を徹底解説【Flutter】