LoginSignup
41
31

More than 3 years have passed since last update.

【Flutter】Dialog Tips集

Last updated at Posted at 2019-08-09

AlertDialog

AlertDialog class - material library - Dart API

画面起動直後にダイアログを表示したい

addPostFrameCallbackメソッドを利用し、画面の描画が終わったタイミングで表示させるようにする。
addPostFrameCallback method - SchedulerBinding class - scheduler library - Dart API

@override
  Widget build(BuildContext context) {
    // 画面の描画が終わったタイミングで表示させる
    WidgetsBinding.instance.addPostFrameCallback((_) => showDialog(
      context: context,
      builder: (_) {
        return AlertDialog(
          title: Center(child: Text("タイトル"),),
          content: Text("ここにメッセージが表示される"),
          actions: <Widget>[
            FlatButton(
              child: Text("キャンセル"),
              onPressed: () => Navigator.pop(context),
            ),
            FlatButton(
              child: Text("OK"),
              onPressed: () => Navigator.pop(context),
            ),
          ],
        );
      },
    ));

    return Scaffold(
      // ...
    );
  }

ボタンを中央寄せで表示したい

引数actionsに定義すると、どうやってもボタンが右寄せになってしまう。
そのため、ColumnやRowなどを利用して、引数contentにボタンを定義する。
その分、ダイアログ下側に余白ができてしまうため、引数contentPaddingを設定して調整する。

showDialog(
        context: context,
        builder: (_) {
          return AlertDialog(
            title: Center(child: Text("タイトル"),),
            content: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Text("ここにメッセージを書く"),
                // アクション用ボタンを定義する
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    FlatButton(
                      child: Text("キャンセル"),
                      onPressed: () => Navigator.pop(context),
                    ),
                    FlatButton(
                      child: Text("OK"),
                      onPressed: () => Navigator.pop(context),
                    ),
                  ],
                ),
              ],
            ),
            // ダイアログの余白を調整
            contentPadding: EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 8.0),
          );
        });

ダイアログ上のアクションを検知させたい

例えば、チェックボックスにチェックが入っているときにだけ、ボタンが押せるようにしたいときは、
setStateメソッドを利用してアクションを検知させるようにする。
setState method - State class - widgets library - Dart API

check_box_dialog.dart
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class CheckBoxDialog extends StatefulWidget {
  CheckBoxDialog(this.title, this.message, this.checkBoxCaption,
      [this.positiveCaption,
      this.onPositive,
      this.negativeCaption,
      this.onNegative]);

  final String title;
  final String message;
  final String checkBoxCaption;
  final String positiveCaption;
  final Function onPositive;
  final String negativeCaption;
  final Function onNegative;

  @override
  CheckBoxDialogState createState() => CheckBoxDialogState();
}

class CheckBoxDialogState extends State<CheckBoxDialog> {
  bool _isChecked = false;

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Center(
        child: Text(widget.title),
      ),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text(widget.message),
          Container(
            padding: EdgeInsets.only(top: 8.0, bottom: 8.0),
            child: CheckboxListTile(
              value: _isChecked,
              title: Text(
                widget.checkBoxCaption,
              ),
              controlAffinity: ListTileControlAffinity.leading,
              // チェックボックスを押下すると以下の処理が実行される
              onChanged: (bool value) {
                setState(() {
                  _isChecked = value;
                });
              },
            ),
          ),
          Container(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                FlatButton(
                    child: Text(widget.negativeCaption),
                    onPressed: () {
                      Navigator.pop(context);
                      if (widget.onNegative != null) {
                        widget.onNegative();
                      }
                    }),
                FlatButton(
                    child: Text(widget.positiveCaption),
                    onPressed: _isChecked
                        ? () {
                            Navigator.pop(context);
                            if (widget.onPositive != null) {
                              widget.onPositive();
                            }
                          }
                        : null),
              ],
            ),
          ),
        ],
      ),
      contentPadding: EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 10.0),
    );
  }
}

呼び出す際は以下のように記述する。

showDialog(
          context: context,
          builder: (_) {
            return CheckBoxDialog(
                "タイトル",
                "ここにメッセージが表示される",
                "チェックを入れる",
                "OK",
                () {
                  // ここにOK時の処理を入れる
                },
                "キャンセル",
                () {
                  // ここにキャンセル時の処理を入れる
                });
          },
        ));

ダイアログ表示時、ダイアログのボタンを押す以外でダイアログが閉じないようにしたい

barrierDismissibleをfalseにし、ダイアログの外をタップしても閉じないようにする。
そして、AlertDialogをWillPopScopeでラップし、OSのバックキー押下時の挙動を上書きし、閉じさせないようにする。
showDialog function - material library - Dart API
WillPopScope class - widgets library - Dart API

showDialog(
        context: context,
        // ダイアログの外をタップしても閉じないようにする
        barrierDismissible: false,
        builder: (_) {
          return WillPopScope(
              // 戻るボタン押下時の処理を上書き
              onWillPop: () async => false,
              child: AlertDialog(
            title: Center(child: Text("タイトル"),),
            content: Text("ここにメッセージが表示される"),
            actions: <Widget>[
              FlatButton(
                child: Text("キャンセル"),
                onPressed: () => Navigator.pop(context),
              ),
              FlatButton(
                child: Text("OK"),
                onPressed: () => Navigator.pop(context),
              ),
            ],
          ),);
        });
41
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
31