【Flutter】文字列入力のできるダイアログを作成してみた

Flutter

iPhoneダイアログのCupertinoAlertDialogを使用して、文字列入力のできるダイアログを作成したのでメモしておきます。

AndroidダイアログのAlertDialogを使用したものはこちらの記事にありましたので、これを参考にさせていただきました。

完成品

ボタンタップ → 入力欄のあるダイアログを表示 → テキスト入力 → OKで戻ると、元の画面に入力した文字列が表示されています

詳細

showDialogでダイアログを表示します。表示するダイアログの種類はCupertinoAlertDialogを採用しています。

ここで、TextFieldを表示させたいのですが、単に

content: TextField(),

とすると、先祖ウィジェットが無いエラー「No Material widget found」が発生します。

このエラーは通常、親ウィジェットとして MaterialApp() と Scaffold() を使用して対象ウィジェットをラップすることで解消しますが、今回はそうも行きません。

そこで、Material()で次のようにラップするのがミソです。

content: Material(
    child: TextField(),
),

以下、ダイアログ表示を含むソースコードになります。初期コードから差し替えるだけで動作します。

class _MyHomePageState extends State<MyHomePage> {
  String _text = '';
  TextEditingController _controller = TextEditingController();

  Future<void> InputDialog(BuildContext context) async {
    return showDialog(
        context: context,
        builder: (context) {
          return CupertinoAlertDialog(
            title: Text('タイトル'),
            content: Material( // Materialでラップするのがミソ!!
              child: TextField(
                enabled: true,
                maxLines:1 ,
                controller: _controller,
                decoration: const InputDecoration(
                  icon: Icon(Icons.create),
                  hintText: 'テキストを入力してください',
                  labelText: '入力 *',
                ),
              ),
            ),
            actions: <Widget>[
              CupertinoDialogAction(
                child: Text('Cancel'),
                isDestructiveAction: true,
                onPressed: () {
                  Navigator.of(context).pop();
                }),
              CupertinoDialogAction(
                child: Text('OK'),
                onPressed: () {
                  print('OK');
                  setState(() {
                    _text = _controller.text;
                  });
                  Navigator.of(context).pop();
                },
              )
            ],
          );
        });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(
        width: double.infinity,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            OutlinedButton(
              child: Text('入力ダイアログを表示'),
              onPressed: () {
                InputDialog(context);
              },
            ),
            SizedBox(height:20),
            Text('↓↓ 入力内容 ↓↓'),
            SizedBox(height:20),
            Text(_text),
          ],
        ),
      ),
    );
  }
}

入力した文字列はTextEditingControllerで取得しています。また、入力欄にはアイコンやラベルを表示するなど、TextFieldをいくらか装飾しています。

色々試してみてください。

タイトルとURLをコピーしました