SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Flutterで始めるモバイルアプリ開発

Flutterではマテリアルデザインを用いたコンポーネントをどう使うのか【テキスト編】

Flutterで始めるモバイルアプリ開発 第13回


テキスト(2)

アプリケーション全体でスタイルを共有する方法

 先ほどの例では、文字のスタイルを個別に新規に作成していました。しかし、実際のアプリケーション開発では、アプリケーション全体で共通のルールが設定されていることが多いと思います。

 そのような場合に用いるのがThemeです。ThemeはMaterialAppに設定するスタイルセットようなものだとイメージすればよいと思います。Themeはテキスト以外のスタイルも指定可能で、こちらを見るとさまざまなスタイルを設定できることがわかります。

 そのThemeの中でテキスト関連を設定するにはTextThemeを用います。このTextThemeには、さまざまなタイプが用意されているので、表示するタイプに合わせてスタイルを使うような流れになります。

 このようなタイプもマテリアルデザインで定義されています。実際にMaterialAppにスタイルを設定した場合の例がリスト2です。

[リスト2]MaterialAppのThemeを使ったスタイルの定義例(lib/Text2Widget.dartの抜粋)
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です。

[リスト3]MaterialAppのThemeを使ったスタイルの使用例(lib/Text2Widget.dartの抜粋)
@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です。

図3:DefaultTextStyleを使ったコードの実行例
図3:DefaultTextStyleを使ったコードの実行例
[リスト4]DefaultTextStyleを使ったコード例(lib/Text3Widget.dartの抜粋)
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です。

図4:WidgetSpanウィジェットを詰まったコードの実行例
図4:WidgetSpanウィジェットを詰まったコードの実行例
[リスト5]RichText内に任意のウィジェットを挿入する場合の例(lib/Text4Widget.dartの抜粋)
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ではどのように使えばよいかまでわかるようになっています。

図5:Googleフォントのサイト
図5:Googleフォントのサイト

 アイコンを使った例がリスト6で、その実行結果が図6です。

図6:アイコンコード例の実行結果
図6:アイコンコード例の実行結果
[リスト6]アイコンを使ったサンプルコード(lib/icon/IconWidget.dartの抜粋)
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が示しているマテリアルデザインというものと非常に強く関連しているということがわかったのではないかと思います。

 次回からはマテリアルデザインを使ったコンポーネントを紹介していきます。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
Flutterで始めるモバイルアプリ開発連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

WINGSプロジェクト について> 有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 ...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/15062 2022/09/05 20:17

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー