skip to Main Content

I’m having a readonly TextFormField widget like this:

TextFormField(
      /// field must neither be focusable, nor must value be editable by input
      canRequestFocus: false,
      readOnly: true,

      controller: _textEditingController,
      keyboardType: TextInputType.none,
      style: TextStyle(
        fontWeight: FontWeight.w400,
        fontSize: 20,
        letterSpacing: 1,
        fontFamily: 'Arial',
      ),
      minLines: 1,
      maxLines: 1,
      validator: null,
      decoration: InputDecoration(
        contentPadding: const EdgeInsets.symmetric(
          vertical: 15.0,
          horizontal: 15.0,
        ),
        errorStyle: TextStyle(
          fontWeight: FontWeight.w400,
          fontSize: 20,
          letterSpacing: 1,
          fontFamily: 'Arial',
          color: Colors.red,
        ),
        errorMaxLines: 3,
        labelText: 'test dskjhfkjshf kdjdfhkjshf ksdjfhkjshf ksjdhfkjshdf kjhfkjshkf skjdfhkjsdjhf kjdhfkhsf',
        labelStyle: MaterialStateTextStyle.resolveWith(
              (Set<MaterialState> states) =>
                  TextStyle(
                    fontWeight: FontWeight.w400,
                    fontSize: 20,
                    letterSpacing: 1,
                    fontFamily: 'Arial',
                  ),
        ),
        floatingLabelStyle: MaterialStateTextStyle.resolveWith(
              (Set<MaterialState> states) {
            return TextStyle(
              fontWeight: FontWeight.w400,
              fontSize: 20,
              letterSpacing: 1,
              fontFamily: 'Arial',
            );
          },
        ),
        counterText: '',
      ),
    )

I’ve tried to set the overflow: TextOverflow.visible of the floatingLabelStyle and the labelStyle properties, but this does not do anything, the example keeps overflowing in an ellipsis.

There is exactly the same issue discussed with regards to the error message overflowing, where the only way is to set the errorMaxLines of the InputDecoration to an integer bigger than 1. But there is no floatingLabelMaxLines or such, so I’m wondering if it’s even possible?

I’m trying this on the iPhone 15 Simulator on a MacBook Pro, iOS 17.

2

Answers


  1. labelText is a string property that will use default styling from the framework. If a more elaborate label is required, consider using [label] instead. Which is a Widget property

    TextFormField(
      controller: txtCtrl,
      decoration: InputDecoration(
        label: const Text(
          'test dskjhfkjshf kdjdfhkjshf ksdjfhkjshf ksjdhfkjshdf kjhfkjshkf skjdfhkjsdjhf kjdhfkhsf',
        ),
        border: const OutlineInputBorder(),
        floatingLabelStyle: MaterialStateTextStyle.resolveWith(
          (Set<MaterialState> states) {
            return const TextStyle(
              fontWeight: FontWeight.w400,
              fontSize: 20,
              letterSpacing: 1,
              fontFamily: 'Arial',
            );
          },
        ),
      ),
    )
    

    result:

    example multi line label

    Since its Text widget, you can customize any styling on it.

    Login or Signup to reply.
  2. TL;DR use InputDecoration.label and pass a Text yourself instead of using InputDecoration.labelText that accepts a string that’s getting ellipsized.


    Let’s take a look at the TextFormField widget source code:

               return UnmanagedRestorationScope(
                 bucket: field.bucket,
                 child: TextField(
                   restorationId: restorationId,
                   controller: state._effectiveController,
                   focusNode: focusNode,
                   decoration: effectiveDecoration.copyWith(errorText: field.errorText),
    

    https://github.com/flutter/flutter/blob/78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9/packages/flutter/lib/src/material/text_form_field.dart#L200C31-L200C31

    It uses TextField widget. Okay. Let’s take a look inside it then:

        if (widget.decoration != null) {
          child = AnimatedBuilder(
            animation: Listenable.merge(<Listenable>[ focusNode, controller ]),
            builder: (BuildContext context, Widget? child) {
              return InputDecorator(
                decoration: _getEffectiveDecoration(),
                baseStyle: widget.style,
                textAlign: widget.textAlign,
                textAlignVertical: widget.textAlignVertical,
    

    https://github.com/flutter/flutter/blob/78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9/packages/flutter/lib/src/material/text_field.dart#L1448C33-L1448C33

    It uses InputDecorator for displaying the decoration (which holds your label). Let’s look at that one then:

        final Widget? label = decoration.labelText == null && decoration.label == null ? null : _Shaker(
          animation: _shakingLabelController.view,
          child: AnimatedOpacity(
            duration: _kTransitionDuration,
            curve: _kTransitionCurve,
            opacity: _shouldShowLabel ? 1.0 : 0.0,
            child: AnimatedDefaultTextStyle(
              duration:_kTransitionDuration,
              curve: _kTransitionCurve,
              style: widget._labelShouldWithdraw
                ? _getFloatingLabelStyle(themeData, defaults)
                : labelStyle,
              child: decoration.label ?? Text(
                decoration.labelText!,
                overflow: TextOverflow.ellipsis,
                textAlign: textAlign,
              ),
            ),
          ),
        );
    

    https://github.com/flutter/flutter/blob/4bc7a44eb69056a6744f576c2cea656d65b656e2/packages/flutter/lib/src/material/input_decorator.dart#L2245-L2249

    Yes. If the InputDecoration.label was null then it indeed passes your labelText to a Text widget that has an overflow explicitly set to ellipsis. But what if we’d put the label property instead then?

    TextField(
      decoration: InputDecoration(
        label: Text(lipsum),
      ),
    )
    

    We get a multiline label! 🙂

    enter image description here

    A small lesson from this comes up: dig into Flutter’s source code! It’s really a source of knowledge, insider info and a way to get even more insight into how Flutter works and does things, and – in case of this problem – how to solve something.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search