0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TextFormFieldはSizedBoxで大きさを変えるのをオススメしない

Posted at

本題

TextFormWidgetはValidationなどができるかなり便利なメソッドですが、
SizedBoxを使用して大きさを変えることはおすすめしない理由と回避策を説明します。

TextFormFieldの一般的なサンプル

スクリーンショット 2024-10-24 210820.png
特に問題ありません。

class MyCustomForm extends StatefulWidget {
  const MyCustomForm({super.key});

  @override
  MyCustomFormState createState() {
    return MyCustomFormState();
  }
}
class MyCustomFormState extends State<MyCustomForm> {
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          TextFormField(
            validator: (value) {
              if (value == null || value.isEmpty) {
                return '入力してください';
              }
              return null;
            },
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 16),
            child: ElevatedButton(
              onPressed: () {
                if (_formKey.currentState!.validate()) {}
              },
              child: const Text('送信'),
            ),
          ),
        ],
      ),
    );
  }
}

TextFormFieldをSizeBoxでラップする場合

  • SizeBoxを設定するとTextFormField自体を小さくできる
    スクリーンショット 2024-10-24 211358.png

  • しかし、送信ボタンを押すと...
    スクリーンショット 2024-10-24 211537.png

上記のようになるのでその回避法を紹介します

    return Form(
      key: _formKey,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Row(
            crossAxisAlignment:
                CrossAxisAlignment.start, 
            children: [
              SizedBox(height: 30, child: Icon(Icons.mail)),
              SizedBox(width: 10), 
              Expanded(
                child: SizedBox(
                  height: 30,
                  child: TextFormField(
                    decoration: InputDecoration(
                      labelText: 'Email', 
                      hintText:
                          'メールアドレスを入力',
                      border: OutlineInputBorder(),
                    ),
                    validator: (value) {
                      if (value == null || value.isEmpty) {
                        return '入力してください';
                      }
                      return null;
                    },
                  ),
                ),
              ),
            ],
          ),
          SizedBox(height: 20), 
          ElevatedButton(
            onPressed: () {
              if (_formKey.currentState!.validate()) {
              }
            },
            child: Text('Submit'),
          ),
        ],
      ),
    );

回避法

- 変更前

          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
-             SizedBox(height: 30, child: Icon(Icons.mail)),
              SizedBox(width: 10),
              Expanded(
                child: SizedBox(
-                 height: 30,
                  child: TextFormField(
                    decoration: InputDecoration(
                      labelText: 'Email',
                      hintText:
                          'メールアドレスを入力',
                      border: OutlineInputBorder(),
-                      
                    ),
                    validator: (value) {
                      if (value == null || value.isEmpty) {
                        return '入力してください';
                      }
                      return null;
                    },
                  ),
                ),
              ),
            ],
          ),
  • 変更後
    スクリーンショット 2024-10-24 213218.png

  • helperTextを追加し、そもそも描画時点でエラーテキストのエリアを確保しておく

  • SizedBoxのheightを調節する

          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
+             SizedBox(height: 32, child: Icon(Icons.mail)),
              SizedBox(width: 10),
              Expanded(
                child: SizedBox(
+                 height: 52,
                  child: TextFormField(
                    decoration: InputDecoration(
                      labelText: 'Email',
                      hintText:
                          'メールアドレスを入力',
                      border: OutlineInputBorder(),
+                     helperText: '',
                    ),
                    validator: (value) {
                      if (value == null || value.isEmpty) {
                        return '入力してください';
                      }
                      return null;
                    },
                  ),
                ),
              ),
            ],
          ),

ちょっと解説

SizeBoxで大きさを変えるとerrorTextを含んだ高さがSizeBoxへ収まるようになってしまい、レイアウトが崩れるようです。

参考

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?