警告のみのダイアログボックス、文字入力ありのダイアログボックスの2種類を扱えるdialogutils.dartを使う。
以下のURLの記事を参考にしました。
Flutter逆引き辞典 Chapter 16 ダイアログでもテキスト入力がしたい
https://zenn.dev/pressedkonbu/books/flutter-reverse-lookup-dictionary/viewer/016-input-text-on-dialog
ソースファイル
以下のファイルをlibフォルダに入れておく。
dialogutil.dart
//dialogutil.dart
import 'package:flutter/material.dart';
class DialogUtils {
DialogUtils._();
/// タイトルのみを表示するシンプルなダイアログを表示する
static Future<void> showOnlyTitleDialog(
BuildContext context,
String title,
) async {
showDialog(
context: context,
builder: (context) {
return AlertDialog(title: Text(title));
},
);
}
/// 入力した文字列を返すダイアログを表示する
static Future<String?> showEditingDialog(
BuildContext context,
String text,
) async {
return showDialog<String>(
context: context,
builder: (context) {
return TextEditingDialog(text: text);
},
);
}
}
/// 状態を持ったダイアログ
class TextEditingDialog extends StatefulWidget {
const TextEditingDialog({super.key, this.text});
final String? text;
@override
State<TextEditingDialog> createState() => _TextEditingDialogState();
}
class _TextEditingDialogState extends State<TextEditingDialog> {
final controller = TextEditingController();
final focusNode = FocusNode();
@override
void dispose() {
controller.dispose();
focusNode.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
// TextFormFieldに初期値を代入する
controller.text = widget.text ?? '';
focusNode.addListener(() {
// フォーカスが当たったときに文字列が選択された状態にする
if (focusNode.hasFocus) {
controller.selection = TextSelection(
baseOffset: 0,
extentOffset: controller.text.length,
);
}
});
}
@override
Widget build(BuildContext context) {
return AlertDialog(
content: TextFormField(
autofocus: true, // ダイアログが開いたときに自動でフォーカスを当てる
focusNode: focusNode,
controller: controller,
onFieldSubmitted: (_) {
// エンターを押したときに実行される
Navigator.of(context).pop(controller.text);
},
),
actions: [
TextButton(
onPressed: () {
debugPrint(controller.text);
Navigator.of(context).pop(controller.text);
},
child: const Text('OK'),
),
],
);
}
}
ダイアログボックス呼び出し
数値を入力する場合について例示する。stateオブジェクトの、build のScaffold()内に、下記を参考に記載する。
ローカル変数textBufで文字列を受取り、初期値を「0」として、nullなら「0」文字列を発生させる。(String?型なのでnullが有り得る)
int.parse(testBuf)でintに変換後、有効な値なら、setState(() {.....}で、共有変数に更新をかける。
async , await が必須。
@override
Widget build(BuildContext context) {
final int age =0;
........
return Scaffold(
appBar: AppBar(....),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
......
ElevatedButton(
onPressed: () async {
String textBuf = await DialogUtils.showEditingDialog(context, '0') ?? '0';
debugPrint(textBuf);
int num = int.parse(textBuf);
if (num > 0) {
setState(() {
selecteddate2 = selecteddate1.add(Duration(days: num),);
});
} // if
},
child: const Text('日数'),
), // ElevatedButton
.......