Flutter-InputDecorator

TextFiledのInputDecorationで以下の様な枠付き(枠にラベル)という表示を使っていたのだけど、調べたところInputDecoratorで実現できた。

ついでにInputDecorationのlabelTextを使った場合のマージン設定にちょっと迷った部分があったのでそこについても記述している。

InputDecorator

InputDecorator class - material library - Dart API
API docs for the InputDecorator class from the material library, for the Dart programming language.

childをInputDecorationで装飾するための基本クラスみたいなものだと思う。

TextFiledの中身を見たら、InputDecorationが定義されている場合childをEditableTextにしてInputDecoratorを呼び出していることが分かった。

InputDecoratorを見つけた経緯は、InputDecorationの装飾を行ったデータの表示を行いたかったため。

当初はTextFiledのenabledをfalseにして表示のみという形で使用していたのだけど、表示がどうやら若干薄くなるようだったのと、TextFiledを常に表示用として使うというのが何か違うという感じがし、代替を探していた。

一応InputDecoratorを使うことで表示的にも心情的にも納得できるものになった。

labelText問題

InputDecorationでlabelText(もしくはlabelがfloatingLabelというものになった場合)に、その文字列の表示領域がInputDecoratorのサイズに考慮されていないということ。

例えば、以下の様な実装でウィジェットを構築した時、labelTextがAppBarに重なってしまう。

    return Scaffold(
      appBar: AppBar(
        title: const Text("Test"),
      ),
      body: Column(children: [
        InputDecorator(
            decoration: const InputDecoration(
              labelText: "File Name",
              border: OutlineInputBorder(),
            ),
            child: Text(_fileName)),

こんな感じに。

この動作はTextFieldも同じだった。

InputDecoratorもしくはInputDecorationのみで対応できないか調べたのだけどだめで、Containerでラップして上側にマージンを配置するしかなかった。

それが以下の実装。

    final height = Theme.of(context).textTheme.subtitle1!.fontSize;
    return Scaffold(
      appBar: AppBar(
        title: const Text("Test"),
      ),
      body: Column(children: [
        Container(
          margin: EdgeInsetsDirectional.only(top: height ?? 20),
          child: InputDecorator(
              decoration: const InputDecoration(
                labelText: "File Name",
                border: OutlineInputBorder(),
              ),
              child: Text(_fileName)),
        ),

上側のマージンの値は使用するフォントのサイズを使用している。
ボーダー上にlabelTextが配置されるので実際のマージン量としてこれでいいかは不明だけど、これでいい感じの隙間が空いた。

またlabelText部に使われるフォントスタイルは以下の優先順位で使われている。

  1. floatingLabelStyle
  2. labelStyle
  3. ThemeData.textTheme.subtitle1
    これはinput_decorator.dart内の実装を追っていって判明したもの。

1,2は多分テーマやコンストラクタに設定されていれば、下位でInputDecorationThemeを取り出して使うことができるのだと思う。

コメント

タイトルとURLをコピーしました