Flutter Text Widgetの使い方 〜 すべてのWidgetを学習

# はじめに

自身の勉強を兼ねて、[`Widget Catalog`](https://flutter.dev/docs/development/ui/widgets)で公開されている全てのWidgetについての解説やソースコードを交えた使い方などをまとめています。

基本方針として、掲載しているサンプルコードは公式サイトのサンプルを流用しています。しかし、公式サイトにはサンプルコードがないものや少し応用したケースはどうするの？という疑問が出てきたりするため、必要に応じてカスタマイズしたり、動作確認済みの自身のコードを掲載しています。間違い等ありましたらご指摘頂けると助かります。

|カテゴリ|Widgetの種類|Qiitaまとめ記事|
|---|---|---|
|[Accesibility](https://flutter.dev/docs/development/ui/widgets/accessibility)|アクセシビリティに関するWidget|Coming Soon|
|[Animation and Motion](https://flutter.dev/docs/development/ui/widgets/animation)|アニメーションに関するWidget|Coming Soon|
|[Assets, Images, and Icons](https://flutter.dev/docs/development/ui/widgets/assets)|Asset/Icon/画像表示に関するWidget|Coming Soon|
|[Async](https://flutter.dev/docs/development/ui/widgets/async)|Asyncパターン (FutureBuilder, StreamBuilder)|Coming Soon|
|[Basics](https://flutter.dev/docs/development/ui/widgets/basics)|最低限抑えるべき基本的なWidget|Coming Soon|
|[Cupertino (iOS-style widgets)](https://flutter.dev/docs/development/ui/widgets/cupertino)|iOS風の各種Widget|Coming Soon|
|[Input](https://flutter.dev/docs/development/ui/widgets/input)|フォームやキー入力等の入力に関するWidget|[Flutter Form入力系Widgetの使い方 〜 すべてのWidgetを学習](https://qiita.com/kurun_pan/items/3378875ff034614f381a)|
|[Interaction Models](https://flutter.dev/docs/development/ui/widgets/interaction)|タッチイベントやその他操作の応答に関するWidget|Coming Soon|
|[Layout](https://flutter.dev/docs/development/ui/widgets/layout)|レイアウトに関するWidget|Coming Soon|
|[Material Components](https://flutter.dev/docs/development/ui/widgets/material)|Android マテリアルデザインの各種Widget|Coming Soon|
|[Painting and effects](https://flutter.dev/docs/development/ui/widgets/painting)|ペイント, エフェクト効果等のWidget|Coming Soon|
|[Scrolling](https://flutter.dev/docs/development/ui/widgets/scrolling)|GridView等のスクロール機能を保有するようなWidget|Coming Soon|
|[Styling](https://flutter.dev/docs/development/ui/widgets/styling)|テーマ等のスタイリングに関わるWidget|Coming Soon|
|[Text](https://flutter.dev/docs/development/ui/widgets/text)|テキスト表示に関わるWidget|<b>今回</b>|

# Text Widgets一覧

文字の表示やその装飾に関する以下のWidgetについて解説します。

|Widget名|用途|
|---|---|
|[Text](https://api.flutter.dev/flutter/widgets/Text-class.html)|テキスト表示用Widgetです。|
|[RichText](https://api.flutter.dev/flutter/widgets/RichText-class.html)|文字列の中で複数の装飾を指定したい場合に利用するWidgetですが、`Text.rich()`の方が便利です。|
|[DefaultTextStyle](https://api.flutter.dev/flutter/widgets/DefaultTextStyle-class.html)|複数のWidgetに対して任意のテキスト装飾を一括適したい場合に利用します。|

# Text

[`Text`](https://api.flutter.dev/flutter/widgets/Text-class.html) Widgetは、単一のスタイルの文字を表示する場合に利用します。Text Widgetは、内部的には`RichText`を利用しています。

## テキストの装飾
文字を装飾する (Style) 場合には、`style`プロパティに[`TextStyle`](https://api.flutter.dev/flutter/painting/TextStyle-class.html)クラスを利用します。

Text Widgetは、単一のスタイルのみ指定可能ですが、Utilityとして[`Text.rich`](https://api.flutter.dev/flutter/widgets/Text/Text.rich.html)というコンストラクタがあります。これを利用することで、後述の`RichText`のように、文字単位で複数の装飾を指定することが可能です。その場合、装飾したい文字単位で[`TextSpan`](https://api.flutter.dev/flutter/painting/TextSpan-class.html)を利用します。

## サンプル
<img width="300" alt="Screenshot_1582214166.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/583faf40-6ffd-9f00-9919-08b67234ab84.png">


```Dart:サンプルコード
Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    Text(
      'Hello, World!',
    ),
    Text(
      '2行目だよ\n3行目はとても長いよ。あいうえおかきくけこさしすせそたちつてと１２３４５６７８９',
      textAlign: TextAlign.end,
      overflow: TextOverflow.ellipsis,
      style: TextStyle(fontWeight: FontWeight.bold, color: Colors.red),
    ),
    const Text.rich(
      TextSpan(
        text: 'Hello', // default text style
        children: <TextSpan>[
          TextSpan(
              text: ' beautiful ',
              style: TextStyle(
                  fontStyle: FontStyle.italic, color: Colors.cyan)),
          TextSpan(
              text: 'world', style: TextStyle(fontWeight: FontWeight.bold)),
        ],
      ),
    )
  ],
);
```

# RichText

[`RichText`](https://api.flutter.dev/flutter/widgets/RichText-class.html)は、デフォルトのスタイルを指定しつつ、複数の`TextSpan`を指定出来るWidgetです。基本的な用途は、[`Text.rich()`](https://api.flutter.dev/flutter/widgets/Text/Text.rich.html)と基本的には同じです。

## サンプル

<img width="300" alt="Screenshot_1582214236.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/9032da59-925d-fac7-ca53-5eb79eff817b.png">


```Dart:サンプルコード
Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    RichText(
      text: TextSpan(
        text: 'Hello ',
        style: DefaultTextStyle.of(context).style,
        children: <TextSpan>[
          TextSpan(
              text: ' beautiful ',
              style: TextStyle(fontStyle: FontStyle.italic)),
          TextSpan(
              text: 'bold', style: TextStyle(fontWeight: FontWeight.bold)),
          TextSpan(text: ' world!'),
        ],
      ),
    )
  ],
);
```

# DefaultTextStyle

[`DefaultTextStyle`](https://api.flutter.dev/flutter/widgets/DefaultTextStyle-class.html)は、複数のWidgetに対して毎度[`TextStyle()`](https://api.flutter.dev/flutter/painting/TextStyle-class.html)を適用するのは面倒なので、一括して特定の装飾を適用したい場合に利用します。

[`DefaultTextStyle.merge`](https://api.flutter.dev/flutter/widgets/DefaultTextStyle/merge.html)を利用すると、指定したWidget以下の全Widgetを再帰的に指定した装飾を適用可能です。

## サンプル

<img width="300" alt="Screenshot_1582215061.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/672ef5f3-a12a-64c0-8ac8-4e13cc21592e.png">

```Dart:サンプルコード
static var _commonTextStyle = TextStyle(
  color: Colors.black,
  fontWeight: FontWeight.w800,
  fontFamily: 'Roboto',
  letterSpacing: 1.0,
  fontSize: 100.0,
);

@override
Widget build(BuildContext context) {
  return Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      DefaultTextStyle(
        style: _commonTextStyle,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[Text('1'), Text('2'), Text('3')],
        ),
      ),
      Container(
        color: Colors.red,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[Text('4'), Text('5'), Text('6')],
        ),
      ),
      DefaultTextStyle.merge(
        style: _commonTextStyle,
        child: Container(
          color: Colors.green,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[Text('7'), Text('8'), Text('9')],
          ),
        ),
      ),
    ],
  );
}
```