top of page

[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ボタンは無効になっています)



最新記事

すべて表示

現象 アプリ内にAdmobを追加して、アプリを起動すると、下記のエラーが発生 java.lang.RuntimeException: Unable to get provider com.google.android.gms.ads.MobileAdsInitProvider 原因 AndroidManifestの書き方が誤っていた。 <meta-data>はactivityと同じ階層にある必要が

概要 Uriを持っていて、Urlに変換したい場合の方法で少し手惑ったので共有します 方法 String url = uri.toString(); これだけです。 最後に ページを開くだけだとUriでもUrlでもいいんですが、WebViewはUrlを要求してくるんですよね。

問題 以前、日本語を含むURLを開くためには、エンコーディングしてやる必要がある、という記事を書きました。 しかし、すでにエンコーディングされているURLを再度エンコーディングしてしまうと、別のURLになってしまいます。 つまり、URLを開く処理の前に、 ・エンコーディングが必要なURLか ・すでにエンコーディングがされているか を判定しないといけないことになります。これは中々煩雑な処理です。 発

靴を大切にしよう!靴管理アプリ SHOES_KEEP

納品:iPhone6.5①.png

靴の履いた回数、お手入れ回数を管理するアプリです。

google-play-badge.png
Download_on_the_App_Store_Badge_JP_RGB_blk_100317.png

「後で読む」を忘れないアプリ ArticleReminder

気になった​Webサイトを登録し、指定時刻にリマインダを送れるアプリです

google-play-badge.png
Download_on_the_App_Store_Badge_JP_RGB_blk_100317.png
bottom of page