【Flutter】条件分岐 if文・三項演算子

目次

概要

基礎として、条件分岐の書き方も知っておこう。
条件分岐は基本的にif
UIを並べるときに使用するif文、処理を行うときとで少々書き方は変わるが、基本的な書き方は同じだ。

ソースコード

アプリ実行部分

import 'package:concentration/TrumpButton/TrumpButtonView.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import 'Default/MyHomePage.dart';

void main() {
  runApp(ProviderScope(child: MyApp()));
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

View表示部分

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  String evenAndOdd = "偶数";
  void _incrementCounter() {
    setState(() {
      _counter++;
      if (_counter % 2 == 0) {
        evenAndOdd = "偶数";
      } else {
        evenAndOdd = "奇数";
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
            Text(
              '$evenAndOdd',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

デモ動画

詳細

if文の書き方は以下の通り。

if ( /* 条件式 */ ) {
  /* 条件式が満たされた時の処理内容 */
} else {
  /* 条件式が満たされなかった時の処理内容 */
}

さて、今回の主役部分は以下のifの部分。

void _incrementCounter() {
  setState(() {
    _counter++;
    if (_counter % 2 == 0) {
      evenAndOdd = "偶数";
    } else {
      evenAndOdd = "奇数";
    }
  });
}

これを先ほどの書き方に当てはめてみよう。

項目設定内容
条件式_counter % 2 == 0
つまり、_counterを2で割った時の余りが0かどうか
条件式が満たされた時の処理内容evenAndOdd = “偶数”;
条件式が満たされなかった時の処理内容evenAndOdd = “奇数”;

つまり、こうすることでevenAndOddの内容を_counterの値で処理を分岐させている。

また、今回はif – elseのパターンだが、条件式を満たさない場合は以下のようにelseを省略しても問題ない。

if ( /* 条件式 */ ) {
  /* 条件式が満たされた時の処理内容 */
}

また、以下のようにして条件式を複数設定することもできる。

if ( /* 条件式1 */ ) {
  /* 条件式1が満たされた時の処理内容 */
} else if ( /* 条件式2 */ ) {
  /* 条件式2が満たされた時の処理内容 */
} else if ( /* 条件式3 */ ) {
  /* 条件式3が満たされた時の処理内容 */
} else {
  /* 全ての条件式が満たされなかった時の処理内容 */
}

この場合は、条件式1から条件式3まで順番に検証していく。そして、条件が満たされるものがあったら、if文内の処理を行い、他の処理は実行しないという処理の流れになる。

三項演算子を使うパターン

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  String evenAndOdd = "偶数";
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
            (_counter % 2 == 0) ?
            Text(
              "偶数",
              style: Theme.of(context).textTheme.headline4,
            ) : Text(
              "奇数",
              style: Theme.of(context).textTheme.headline4,
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

これは_incrementCounter()メソッドの中で分岐処理を書くのではなく、childrenで分岐をさせているパターン。
具体的には以下の箇所だ。

(_counter % 2 == 0) ? 
  Text("偶数",
    style: Theme.of(context).textTheme.headline4,
  ) : Text("奇数",
    style: Theme.of(context).textTheme.headline4,
  )

この書き方は三項演算子と呼ばれる。
if文はあくまで処理を書くので、UIの分岐には使えない。
そのため、上記のようにして書く。

三項演算子の書き方は以下の通り。

(/* 条件式 */) ? /* 条件式を満たしている時の内容 */ : /* 条件式を満たしていない時の内容 */

今回の例では以下のように対応している。

項目設定内容
条件式_counter % 2 == 0
条件式を満たしている時の内容Text(“偶数”, style: Theme.of(context).textTheme.headline4,)
条件式を満たしていない時の内容Text(“奇数”, style: Theme.of(context).textTheme.headline4,)

つまり、偶数の時は「偶数」と書かれた文字列を、そうでないければ「奇数」と書かれた文字列をUIとして採用して画面に表示するという実装になる。

参考ページ