LoginSignup
1
1

More than 1 year has passed since last update.

FlutterのTextFieldのデザインを自由自在に変更する

Last updated at Posted at 2021-11-24

はじめに

Flutterでテキスト入力をさせる場合、TextField(もしくはTextFormField)を使用しますが、OutlineInputBorderを使用するとPaddingがかなり大きめに取られてしまい、contentPaddingEdgeInsets.zeroを指定してもPaddingは消えてくれません。

そこで、InputDecoration.collapsedを使うことでPaddingを無くし、Containerでラップしてデザインする方法を考えました。
InputDecoration.collapsedはサイズが入力フィールドと同じになり(Paddingが0)、出来る装飾が限られます。

元になるTextField

TextField(
  controller: _textController,
  decoration: InputDecoration(
    filled: true,
    fillColor: Colors.grey,
    border: OutlineInputBorder(
      borderRadius: BorderRadius.circular(4),
      borderSide: const BorderSide(
        width: 0,
        style: BorderStyle.none,
      ),
    ),
    prefixIcon: const Icon(Icons.search),
    hintText: '検索',
  ),
)

今回は、枠線なしで縁は丸くします。

Containerでデザインする

Container(
  padding: const EdgeInsets.all(10),
  decoration: BoxDecoration(
    color: Colors.grey,
    borderRadius: BorderRadius.circular(4),
  ),
  child: Row(
    children: <Widget>[
      const Icon(Icons.search),
      const Padding(padding: EdgeInsets.only(right: 8)),
      Expanded(
        child:TextField(
          decoration: const InputDecoration.collapsed(
            hintText: '検索',
            border: OutlineInputBorder(
              borderSide: BorderSide(
                width: 0,
                style: BorderStyle.none,
              ),
            ),
          ),
        ),
      ),
    ],
  ),
)

filledやfillColorはContainerで行うので消します。
InputDecoration.collapsedではprefixIconを付けることができないので、RowIconTextFieldを横に並べます。また、アイコンが近すぎるのでPaddingで調整します。
TextFieldExpandedでラップしないとダメです。

とりあえずこれで好きなデザインに出来るようにはなりましたが、Container部分やIcon部分をタップしてもTextFieldにフォーカスが移らないため、めちゃくちゃ押しにくくなってしまいました。
なので、さらにGestureDetectorでラップしてonTapでフォーカスを渡すようにします。

最終的なコード

GestureDetector(
  onTap: () => _focusNode.requestFocus(),
  child: Container(
    padding: const EdgeInsets.all(10),
    decoration: BoxDecoration(
      color: Colors.grey,
      borderRadius: BorderRadius.circular(4),
    ),
    child: Row(
      children: <Widget>[
        const Icon(Icons.search),
        const Padding(padding: EdgeInsets.only(right: 8)),
        Expanded(
          child:TextField(
            focusNode: _focusNode,
            decoration: const InputDecoration.collapsed(
              hintText: '検索',
              border: OutlineInputBorder(
                borderSide: BorderSide(
                  width: 0,
                  style: BorderStyle.none,
                ),
              ),
            ),
          ),
        ),
      ],
    ),
  ),
);

だいぶコードが長くなってしまったので、StatelessWidgetなどにして使いまわしやすいようにしたほうが良いかもしれないですね。

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