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?

無事、Widget LabにStatefulWidgetを追加できるようになったので
記念すべき初StatefulWidgetとして、
TextFieldのページを追加しました。

しかし
初っ端にこのWidgetに取り掛かったことを
正直、後悔しています。

プロパティ(今までパラメータと呼んでいましたが多分こっちが正解)
が多すぎるんです。。。

現在のFlutter API(2026年6月時点)で
Propertiesとして記載されているものは64個もあります。
(ChatGPT調べ)

その中から、役に立ちそうなものや
学習価値の高いものを厳選して
アプリに実装しましたが
それでもかなりの項目数になってしまいました。

互いに影響し合うプロパティや
同時に指定すると期待通りに動かない組み合わせもとても多いです。
何度もクラッシュして
本当に手こずりました。

TextFieldのプロパティの
全てを説明するのは無理そうなので、
特によく使いそうなものと
マニアックすぎて他に解説している人がいなさそうなもの、
エラーに遭遇した組み合わせなどを
何回かに分けて紹介したいと思います。

今回はまず、その1として
TextFieldのプロパティの概要を
まとめてみました。

TextFieldのプロパティツリー

ツリー形式にすると、こんな感じです。

TextField
├─ controller
├─ focusNode
├─ keyboardType
├─ textInputAction
├─ style
├─ textAlign
├─ obscureText
├─ maxLines
├─ minLines
├─ maxLength
├─ readOnly
├─ enabled
├─ autofocus
├─ expands
├─ cursorColor
├─ cursorWidth
├─ cursorHeight
├─ cursorRadius
├─ onChanged
├─ onSubmitted
├─ onTap
├─ onEditingComplete
├─ inputFormatters
├─ scrollController
├─ scrollPhysics
├─ selectionControls
├─ mouseCursor
├─ restorationId
└─ decoration 

この時点ですでに多すぎて読む気が失せますが
例えば、枠線の太さを変更したい!
って思ってプロパティを探してみても、それらしきものは見当たりません。

見た目の設定の大半は、decorationというプロパティに
InputDecorationという設定クラスを渡して調整するからです。

中身はこんな感じです。

TextField
└─ decoration: InputDecoration(
     hintText: ...,
     labelText: ...,
     prefixIcon: ...,
     border: ...,
     ...
   )

見た目に関する細かな設定の大部分が
InputDecoration の中にまとめられています。

そんなわけで、decorationの中身もツリーにすると
こうなります。

クリックで表示
TextField
├─ controller
├─ focusNode
├─ keyboardType
├─ textInputAction
├─ style
├─ textAlign
├─ obscureText
├─ maxLines
├─ minLines
├─ maxLength
├─ readOnly
├─ enabled
├─ autofocus
├─ expands
├─ cursorColor
├─ cursorWidth
├─ cursorHeight
├─ cursorRadius
├─ onChanged
├─ onSubmitted
├─ onTap
├─ onEditingComplete
├─ inputFormatters
├─ scrollController
├─ scrollPhysics
├─ selectionControls
├─ mouseCursor
├─ restorationId
└─ decoration: InputDecoration 
    ├─ label
    ├─ labelText
    ├─ labelStyle
    ├─ floatingLabelStyle
    ├─ floatingLabelBehavior
    ├─ floatingLabelAlignment
    │
    ├─ hint
    ├─ hintText
    ├─ hintStyle
    ├─ hintMaxLines
    │
    ├─ helper
    ├─ helperText
    ├─ helperStyle
    │
    ├─ error
    ├─ errorText
    ├─ errorStyle
    ├─ errorMaxLines
    │
    ├─ prefix
    ├─ prefixText
    ├─ prefixStyle
    ├─ prefixIcon
    ├─ prefixIconColor
    ├─ prefixIconConstraints
    │
    ├─ suffix
    ├─ suffixText
    ├─ suffixStyle
    ├─ suffixIcon
    ├─ suffixIconColor
    ├─ suffixIconConstraints
    │
    ├─ icon
    ├─ iconColor
    │
    ├─ filled
    ├─ fillColor
    ├─ focusColor
    ├─ hoverColor
    │
    ├─ border
    ├─ enabledBorder
    ├─ focusedBorder
    ├─ disabledBorder
    ├─ errorBorder
    ├─ focusedErrorBorder
    │
    ├─ contentPadding
    ├─ isDense
    ├─ isCollapsed
    ├─ constraints
    │
    ├─ alignLabelWithHint
    ├─ semanticCounterText
    ├─ counter
    ├─ counterText
    ├─ counterStyle
    ├─ maintainHintHeight
    └─ maintainHintSize

このように
枠線の種類や太さ、角の丸みだけでなく、

  • ラベルやヒント文字
  • エラーメッセージ
  • 前後に表示する文字やアイコン
  • 背景色や余白

なども、すべて InputDecoration のプロパティとして設定します。

ややこしいことに
decoration: InputDecorationの中の
labelStylehintStyle なども
TextStyle というクラスなので、
中にはたくさんのプロパティが含まれています。

TextStyle
├─ color
├─ fontSize
├─ fontWeight
├─ fontStyle
├─ letterSpacing
├─ wordSpacing
├─ height
├─ decoration
├─ shadows
├─ foreground
├─ background
└─ overflow

同じく、InputDecoration の中の
borderも単なる色や数値ではなく
クラスを渡す仕様になっています。
そのため、設定はさらに階層化されています。

まず、borderと言ってもいくつも種類があります。
実際によく使うのはこの3つ。

  • OutlineInputBorder 四角い枠
  • UnderlineInputBorder 下線のみ
  • InputBorder.none 枠線なし

これらのBorderもクラスなので
枠線の色や太さ、角の丸みなどの設定は、その中のプロパティで行います。

例えば、四角い枠を使って
枠線の色や太さを設定したい時はこのような書き方になります。

TextField(
  decoration: InputDecoration(
    border: OutlineInputBorder(
      borderRadius: BorderRadius.circular(8),
      borderSide: BorderSide(
        color: Colors.blue,
        width: 2,
      ),
    ),
  ),
)

Borderについて

もう少し、このborder の中を掘り下げてみます。
borderの中にはborderSideborderRadiusがあります。

border : InputBorder
├─ UnderlineInputBorder
│   ├─ borderSide
│   └─ borderRadius
│
├─ OutlineInputBorder
│   ├─ borderSide
│   ├─ borderRadius
│   └─ gapPadding
│
└─ InputBorder.none

そして、それぞれのborderSide はこうなっています。

borderSide : BorderSide
├─ color
├─ width
├─ style
└─ strokeAlign

ところで
上の方で示したプロパティツリーを見ると
このようになっています。

 ├─ border
 ├─ enabledBorder
 ├─ focusedBorder
 ├─ disabledBorder
 ├─ errorBorder
 ├─ focusedErrorBorder

ということは、
このそれぞれに

borderSide : BorderSide
├─ color
├─ width
├─ style
└─ strokeAlign

があるのでしょうか?

そのとおりなのです。
TextFieldは、

  • 入力状態になっているか
  • エラーになっているか

などの状態によって
別々のborder設定をすることができるのです。

InputDecoration
├─ border
│   ├─ borderRadius
│   ├─ gapPadding
│   └─ borderSide
│       ├─ color
│       ├─ width
│       ├─ style
│       └─ strokeAlign
│
├─ enabledBorder
│   ├─ borderRadius
│   ├─ gapPadding
│   └─ borderSide
│       ├─ color
│       ├─ width
│       ├─ style
│       └─ strokeAlign
│
├─ focusedBorder
│   ├─ borderRadius
│   ├─ gapPadding
│   └─ borderSide
│       ├─ color
│       ├─ width
│       ├─ style
│       └─ strokeAlign
│
├─ disabledBorder
│   ├─ borderRadius
│   ├─ gapPadding
│   └─ borderSide
│       ├─ color
│       ├─ width
│       ├─ style
│       └─ strokeAlign
│
├─ errorBorder
│   ├─ borderRadius
│   ├─ gapPadding
│   └─ borderSide
│       ├─ color
│       ├─ width
│       ├─ style
│       └─ strokeAlign
│
└─ focusedErrorBorder
    ├─ borderRadius
    ├─ gapPadding
    └─ borderSide
        ├─ color
        ├─ width
        ├─ style
        └─ strokeAlign

そして、これらは設定値として持ってはいますが
実際に表示されるのはひとつだけです。

さらにややこしい話

なるほど、状態ごとのBorderがあることは理解しました。
でも、最初に出てきた3種類のボーダー

  • OutlineInputBorder 四角い枠
  • UnderlineInputBorder 下線のみ
  • InputBorder.none 枠線なし

これはどこ行っちゃったの??

実は、この6個のBorderそれぞれが
InputBorderを持っています。

InputDecoration
├─ border               -> OutlineInputBorder(...)
├─ enabledBorder        -> OutlineInputBorder(...)
├─ focusedBorder        -> OutlineInputBorder(...)
├─ disabledBorder       -> OutlineInputBorder(...)
├─ errorBorder          -> OutlineInputBorder(...)
└─ focusedErrorBorder   -> OutlineInputBorder(...)

すべての状態が
同じ種類のInputBorderである必要はありません。

イメージとしてはこんな感じです。

ChatGPT Image 2026年6月20日 08_37_51.png

実際に
このように書くと

TextField(
            decoration: InputDecoration(
              labelText: 'Tap me',

              // 通常時は下線
              enabledBorder: UnderlineInputBorder(),

              // フォーカス時は四角い枠
              focusedBorder: OutlineInputBorder(),
            ),
          ),

タップすることで
このように変化します。

Frutterのデフォルトだと
エラー時には勝手に赤い枠線になったりするのですが
それはこのあたりのプロパティで設定されているようです。


では、Borderのプロパティを設定する時は
いちいち6個全ての設定を書かないといけないのでしょうか?

そうではありません。
普通は border を1つ指定するだけです。

例えば下線のみなら、

TextField(
  decoration: const InputDecoration(
    labelText: 'Name',
    border: UnderlineInputBorder(),
  ),
)

これだけで十分。

border(無印)は

enabledBorder や focusedBorder が指定されていないときに使われる
デフォルトのBorder

という役割になっているのです。

実はこの仕様、便利なようで
とんでもなく厄介なのですが
今回はここまでにしておきます。

(つづく)

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?