[Flutter/dart]文字入力用フォームを作成する
概要
アプリ内でユーザに文字入力をしてもらうためのフォームを作る方法をご紹介します。
方法
新たにStatefulWidgetを作成します。なぜかというと、入力された内容に応じて「OK」ボタンを押せるかを変えたいからです。(例えばTwitterは文字数が1~140じゃないとツイートボタンを押せないですよね)
class MyTextInput extends StatefulWidget{
final bool Function(String) buttonEnable;//入力文字列をチェックする関数
String title; //入力フォームのタイトル
int maxLen; //入力文字列の最長
MyTextInput({this.buttonEnable, this.title, this.maxLen});
@override
State<StatefulWidget> createState() {
return MyTextInputState();
}
}
class MyTextInputState extends State<MyTextInput>{
bool _enableButton=false;
TextEditingController controller;
@override
void initState() {
controller=TextEditingController();
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(widget.title),
content: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children:[
TextField(
controller: controller,
maxLength: widget.maxLen,
onChanged: (text){
_enableButton=widget.buttonEnable(text); //1
setState(() {});
},
),
SizedBox(height: 8,),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FlatButton(
child: Text("Cancel"),
textColor: Colors.blue,
onPressed: ()async{Navigator.of(context).pop("");}
),
FlatButton(
child: Text("OK"),
textColor: Colors.blue,
onPressed: _enableButton? ()async{
Navigator.of(context).pop(controller.text);
}: null //2
),
],
),
]
)
);
}
}
このクラスは3つの引数をとります。buttonEnableが入力文字列をチェックする関数です。TextFieldのonChangeイベントで入力内容を都度チェックし(1)、問題ある場合はFlatButtonのonPressedをnullにします(2)。こうすることで、入力内容が規定外の場合はOKボタンを押せなくなります。
このクラスは以下のように使えます。
class MyHomePageState extends State<MyHomePage>{
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('demo'),
),
body: Container(
child: Center(
child: RaisedButton(
child: Text('input text'),
onPressed: ()async{
String input=await showInputTextForm(context);
//1 入力内容を処理
},
),
)
)
);
}
Future<String> showInputTextForm(BuildContext context)async{
String input=await showDialog<String>(
context: context,
builder:(context)=> MyTextInput(buttonEnable: checkInput, maxLen: 100, title: "入力",)
);
if (input==null){
input="";
}
return input;
}
bool checkInput(String text){
return text.length>0;
}
}
この例では文字数が0以上であればOKボタンを押せるようにしています。もちろんもっと複雑な処理も可能です(文字数の上限や既存のデータと重複がないか、など)。
1の部分で取得した入力文字列に応じた処理を書いてください。Cancelボタンが押されたら空白文字列が返されるので場合分けしてください。
こんな感じの入力フォームが表示されます。(何も入力していないのでOKボタンは無効になっています)

最新記事
すべて表示現象 あるアイコンは長押し時に所定の動作を実行します これを実現するために、GestureDetectorのonLongPressに処理を登録していました しかしいざビルドしてみると、アイコンが表示されたタイミングで処理が実行されてしまいました 以下が該当部分のソースコードです。 さあ、どこが間違っているでしょう? return GestureDetector( child: Containe
前提 以下のようなケースを考えます。 アイテムの一覧がある ある1つのアイテムの詳細を表示するページがある 詳細ページではそのアイテムの削除ができる 削除したら他のページ(一覧ページなど)に戻る これはアプリではよくあるパターンだと思います。 課題 reduxパターンを用いている、より具体的にはProviderで状態を管理している場合、以下のような構成になっているのではないでしょうか? アプリ全体
やりたいこと Reduxで状態管理をする。状態はAppStateとする。 アプリ開始時にリモートのデータベースからデータの取得を開始 データを取得 取得中は待機マークを表示 取得したデータからAppStateを作成 作成したAppStateを元にUIを描画 方法 3、4、5を実現するためには、「取得完了」のフラグをAppStateに追加しましょう(※1)。 ビューはこのフラグを見て表示を切り替えま