はじめに
Flutterでテキスト入力をさせる場合、TextField
(もしくはTextFormField
)を使用しますが、OutlineInputBorder
を使用するとPaddingがかなり大きめに取られてしまい、contentPadding
にEdgeInsets.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を付けることができないので、Row
でIcon
とTextField
を横に並べます。また、アイコンが近すぎるのでPadding
で調整します。
TextField
は Expanded
でラップしないとダメです。
とりあえずこれで好きなデザインに出来るようにはなりましたが、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などにして使いまわしやすいようにしたほうが良いかもしれないですね。