テキスト(2)
アプリケーション全体でスタイルを共有する方法
先ほどの例では、文字のスタイルを個別に新規に作成していました。しかし、実際のアプリケーション開発では、アプリケーション全体で共通のルールが設定されていることが多いと思います。
そのような場合に用いるのがThemeです。ThemeはMaterialAppに設定するスタイルセットようなものだとイメージすればよいと思います。Themeはテキスト以外のスタイルも指定可能で、こちらを見るとさまざまなスタイルを設定できることがわかります。
そのThemeの中でテキスト関連を設定するにはTextThemeを用います。このTextThemeには、さまざまなタイプが用意されているので、表示するタイプに合わせてスタイルを使うような流れになります。
このようなタイプもマテリアルデザインで定義されています。実際にMaterialAppにスタイルを設定した場合の例がリスト2です。
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
// (1) テキストのスタイルを設定する
textTheme: TextTheme(
bodyText1: TextStyle(
color: Colors.black54,
fontWeight: FontWeight.normal,
fontStyle: FontStyle.normal,
decoration: TextDecoration.none,
fontSize: 20
),
),
),
home: Text1Widget()
);
(1)のようにbody1のスタイルが設定できます。設定しないタイプはデフォルトの値が設定されます。続いて、設定したスタイルを利用する場合がリスト3です。
@override
Widget build(BuildContext context) {
// (1) 設定されているTextThemeを取得
final textTheme = Theme.of(context).textTheme;
// (2) 設定されているテーマを上書きする
final boldStyle = textTheme.bodyText1?.copyWith(
color: Colors.redAccent,
fontSize: 40,
fontWeight: FontWeight.bold
);
return Container(
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 省略
RichText(
maxLines: 1,
overflow: TextOverflow.ellipsis,
text: TextSpan(
children: [
TextSpan(text : 'さあ', style: textTheme.bodyText1),
TextSpan(text : 'Flutter', style: boldStyle),
TextSpan(text : "を始めましょう", style: textTheme.bodyText1)
]
)),
],
)
);
}
MaterialAppに設定されているThemeを取得するには、(1)のようにTheme.of()メソッドを使って取得します。また、取得したスタイルをそのまま使用するだけではなく、一部だけ上書きしたスタイルを使いたい場合もあります。そのような場合には、(2)のようにTextStyleのcopyWith()メソッドを使って部分的な上書きが可能です。
まとめてスタイルを指定する
これまでスタイルを個別にすべて指定していましたが、配下のコンポーネントはすべて同じスタイルを適用したい場合があります。そのような場合に利用するのがDefaultTextStyleです。
ただし、注意点として適用されるのがTextだけになり、RichTextは関係ありません。リスト4がコード例でその実行結果が図3です。
return Container(
color: Colors.white,
// (1) このウィジェット配下のスタイルを指定
child : DefaultTextStyle(
style: textStyle,
child: Column (
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Hello World'),
Text('さあ'),
// (2) 個別に指定
Text('Flutter',style: boldStyle),
Text('をはじましょう')
]
)
)
);
(1)がDefaultTextStyleの使用例でstyleプロパティでスタイルを指定します。このウィジェット配下、つまり、このウィジェットツリー上に含まれるTextのデフォルトスタイルが適用されます。
そして、個別に指定をする場合には、これまでと同じように(2)のように指定します。このDefaultTextStyleがウィジェットであるというのは、少々興味深い考え方だなと筆者は感じましたが、UIウィジェットとして定義できることで構造ツリー上に定義できるようになっている点が便利と言えるでしょう。
文章内にテキスト以外を挿入する
ここまでは主にスタイルの使い方を紹介してきましたが、より表現力が高い文章を表示したい場合に必要のテクニックを紹介します。
例えば、文章内にテキスト以外のオブジェクトを差し込みたい場合がよくあります。このような場合に利用するウィジェットがWidgetSpanです。ウィジェットであれば挿入可能ですが、よくあるケースとしては画像を挿入するようなことが多いと思います。その利用例がリスト5で、実行した結果が図4です。
return Container(
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// (省略)
RichText(
text: TextSpan(
children: [
TextSpan(text : 'さあ', style: textTheme.bodyText1),
// (1) 画像を差し込み
WidgetSpan(
child : SizedBox(
height: 40,
child: Image.asset('assets/images/logo_flutter_horizontal.png'),
)
),
TextSpan(text : "を始めましょう", style: textTheme.bodyText1)
]
),
),
// (省略)
RichText(
text: TextSpan(
children: [
TextSpan(text : 'さあ', style: textTheme.bodyText1),
// (2) 位置揃えを指定する
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child : SizedBox(
height: 40,
child: Image.asset('assets/images/logo_flutter_horizontal.png'),
)
),
TextSpan(text : "を始めましょう", style: textTheme.bodyText1)
]
),
),
],
)
);
(1)は画像を指定したを文章内に挿入しています。そして、(2)では同じ画像を挿入していますが、alignmentを指定し位置を中央にしています。レイアウトウィジェットを利用しても同じようなことが可能なので、目的に応じてどちらの方法で実現するかを選択すればよいと思います。
アイコン
以前にもアイコンについては簡単には触れましたが、改めてマテリアルデザインに関連して紹介したいと思います。Flutterで利用できるアイコンは、こちらで紹介されている「System icons」に該当するものになります。
また、実際に、利用できるアイコンは、Googleフォントで参照することが可能です。このサイトでは、図5のようにアイコンを選択すると、Flutterではどのように使えばよいかまでわかるようになっています。
アイコンを使った例がリスト6で、その実行結果が図6です。
return Container(
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// (1) アイコンの指定
Icon(Icons.home_outlined),
// (2) サイズと色の指定
Icon(
Icons.home,
size: 40,
color: Colors.blueAccent,
),
Icon(
Icons.account_box,
color: Colors.redAccent,
size: 45,
)
],
),
)
(1)のようにアイコンを指定します。また、サイズ、色を指定する場合には(2)のようにします。今回の例のようにアイコンのみをコンポーネントを表示する例は少なく、多くの場合にはボタンなどやメニューなどと合わせて利用するケースが多くなるはずです。
まとめ
今回はテキストとアイコンのみの紹介ですが、FlutterのMaterialコンポーネントというものが、Googleが示しているマテリアルデザインというものと非常に強く関連しているということがわかったのではないかと思います。
次回からはマテリアルデザインを使ったコンポーネントを紹介していきます。
