flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
162.21k stars 26.64k forks source link

TextFormField doesn't render its border as said in the docs. #28862

Open feinstein opened 5 years ago

feinstein commented 5 years ago

I think there's a problem in the way TextFormField deals with its border.

As far as I understand from the docs, the border parameter will take an InputDecoration shape and will substitute the color and weight from the others parameters like enabledBorder and focusedBorder.

So if this is true, the following code should work:

TextFormField(
  decoration: InputDecoration(
    enabledBorder: const OutlineInputBorder(
      borderSide: const BorderSide(color: Colors.orange),
     ) ,
     focusedBorder: const OutlineInputBorder(
       borderSide: const BorderSide(color: Colors.white),
     ) ,
     border: OutlineInputBorder(
       borderRadius: BorderRadius.circular(100)
     )
  ),
)

In this code I define a border shape where corners are rounded and ONLY the color of the border changes if it's enabled or focused.

But in fact what I am seeing is that the shape in border is being totally ignored and the TextFormField is rendered as a square with orange or white colors, no rounded edges.

The only way I can get it to work is with this very repetitive code:

TextFormField(
  decoration: InputDecoration(
    enabledBorder: OutlineInputBorder(
      borderSide: BorderSide(color: Colors.orange),
      borderRadius: BorderRadius.circular(100)
    ) ,
    focusedBorder: OutlineInputBorder(
      borderSide: BorderSide(color: Colors.white),
      borderRadius: BorderRadius.circular(100)
    ) ,
    border: OutlineInputBorder(
      borderRadius: BorderRadius.circular(100)
    )
  ),
)

Is this really the correct way to achieive this?

I tried @HansMuller short test case here: https://github.com/flutter/flutter/pull/19694#issuecomment-469376553 but since it doesn't have a rounded border it doesn't match what I see. I think the problem lies in borderRadius: BorderRadius.circular(100).

HansMuller commented 5 years ago

OutlineInputBorder's borderRadius parameter defaults to BorderRaidus.circular(4) so there's no avoiding providing that parameter for each InputDecoration border. This version of the test case appears to do what you want: https://gist.github.com/HansMuller/7b9c44ee67e9fa260678f423af6350bd, albeit with a smaller border radius.

border

That said, I can see two real problems here:

feinstein commented 5 years ago

so there's no avoiding providing that parameter for each InputDecoration border.

Well this is the case then I think the docs should be modified, the way I understood them was that the border would be maintained as defined by boder and only color and minor things would change. Maybe what will change and what will not should be better documented?

Using large border radius values (like 100) breaks the trig code that computes the focused border's gap.

Yes, I saw some weird behavior using the label, so I am only using hint.

I assume that what you're looking for is a "stadium" border outline. What we probably need for that case is a StadiumInputBorder class.

Yes, I want a "stadium" border outline and created an issue for it here #28611 already.

zekiegitimcom commented 5 years ago

I have same problem with TextField(), i think its a bug.

My InputDecoration code:

InputDecoration( 
    labelText: 'Insert your name...',

    focusedBorder: OutlineInputBorder(
      borderSide: BorderSide(
        color: Colors.amberAccent,
        width: 3,
      ),
      borderRadius: const BorderRadius.all(Radius.circular(0)),
    ),

    errorBorder: OutlineInputBorder(
      borderSide: BorderSide(
        color: Colors.red,
        width: 3,
      ),
      borderRadius: const BorderRadius.all(Radius.circular(0)),
    ),

    enabledBorder: OutlineInputBorder(
      borderSide: BorderSide(
        color: Colors.indigo,
        width: 3,
      ),
      borderRadius: const BorderRadius.all(Radius.circular(0)),
    ),

    disabledBorder: OutlineInputBorder(
      borderSide: BorderSide(
        color: Colors.blueGrey,
        width: 3,
      ),
      borderRadius: const BorderRadius.all(Radius.circular(0)),
    ),

    border: UnderlineInputBorder(),
),

According to code, there are some situations:

Advices:

  1. InputDecoration class need an errorFocusedBorder: parameter and don't need border: parameter. It's just a mess.

  2. focusedBorder: parameter should change or deprecate with enabledFocusedBorder: parameter.

TahaTesser commented 4 years ago

Hi @feinstein Do you think this issue still valid? Thank you

feinstein commented 4 years ago

Yes, I would still like to see a StadiumInputBorder.

mugilan-viewzen commented 2 years ago

I have same problem with TextField(), i think its a bug.

My InputDecoration code:

InputDecoration( 
    labelText: 'Insert your name...',

    focusedBorder: OutlineInputBorder(
      borderSide: BorderSide(
        color: Colors.amberAccent,
        width: 3,
      ),
      borderRadius: const BorderRadius.all(Radius.circular(0)),
    ),

    errorBorder: OutlineInputBorder(
      borderSide: BorderSide(
        color: Colors.red,
        width: 3,
      ),
      borderRadius: const BorderRadius.all(Radius.circular(0)),
    ),

    enabledBorder: OutlineInputBorder(
      borderSide: BorderSide(
        color: Colors.indigo,
        width: 3,
      ),
      borderRadius: const BorderRadius.all(Radius.circular(0)),
    ),

    disabledBorder: OutlineInputBorder(
      borderSide: BorderSide(
        color: Colors.blueGrey,
        width: 3,
      ),
      borderRadius: const BorderRadius.all(Radius.circular(0)),
    ),

    border: UnderlineInputBorder(),
),

According to code, there are some situations:

* if your TextField's `enabled:` is **_false_**,
  -- then work **`disabledBorder:`** ,
  --- there is **NO FOCUS!** in this situation, because it is disabled.

* if your TextField's `enabled:` is **_true_**,
  -- then work **`enabledBorder:`** ,
  --- there is a **FOCUS!**
  ---- when i focus TextField, then work **`focusedBorder:`** .

* if you have an error (or you fill `errorText:` in your TextField),
  -- then work **`errorBorder:`** ,
  --- there is a **FOCUS!**
  ---- when i focus TextField, **i expect `focusedBorder:` will work** again. BUT NOT WORKING
  ----- **`errorBorder:`** and **`border:`** work together. (`border:` **only work in this situation**.)

Advices:

1. InputDecoration class need an **`errorFocusedBorder:`** parameter and don't need `border:` parameter.
   It's just a mess.

2. `focusedBorder:` parameter should change or deprecate with **`enabledFocusedBorder:`** parameter.

This bug is still there.

justinmc commented 1 year ago

I recently made some changes (https://github.com/flutter/flutter/pull/93933) that help eliminate the gap in the border that can be seen in this issue. Still not a full fix for a stadium border though.

ruialves35 commented 2 weeks ago

It's been 5 years since this issue came out and there is no solution. Why is there a contentPadding that works for both content AND label? How hard is it to add a new field labelPadding and work with that on the label, and use contentPadding only for content as it was suppose to? What is preventing this improvement, as it seems so easy to extend? This is preventing the development of so many custom dropdowns.

I did not understand that idea of the "stadiumInputBorder", is there any solution?

And I'm sorry if I'm being so much judgemental even if I'm a beginner but this is not making much sense to me :')

feinstein commented 2 weeks ago

Hi @ruialves35, welcome to Flutter. I will try to answer some of your questions:

  1. In a nutshell, the code that draws a TextField's border is not simple, there are parts that are kinda more "low level", with pixel calculations (to draw the lines and curves) and all of the parameters to decide how to draw them, come from another "place". I am simplifying things here, just so you understand that's not a quick fix.
  2. Stadium is the shape of a curved square, like a football stadium shape. The idea is to have a new and more customisable shape that we can plug-in there.
  3. The reason why this has not being done yet is probably because there are other higher priority tasks do be done.
  4. Be careful when asking questions regarding time estimates or why things are not done. They are not welcome in the community, they generate unnecessary friction with the Flutter team, as they have lots of stuff to do. This kind of question can get you banned, take a look at the community guidelines please.
ruialves35 commented 2 weeks ago

Hi @ruialves35, welcome to Flutter. I will try to answer some of your questions:

  1. In a nutshell, the code that draws a TextField's border is not simple, there are parts that are kinda more "low level", with pixel calculations (to draw the lines and curves) and all of the parameters to decide how to draw them, come from another "place". I am simplifying things here, just so you understand that's not a quick fix.
  2. Stadium is the shape of a curved square, like a football stadium shape. The idea is to have a new and more customisable shape that we can plug-in there.
  3. The reason why this has not being done yet is probably because there are other higher priority tasks do be done.
  4. Be careful when asking questions regarding time estimates or why things are not done. They are not welcome in the community, they generate unnecessary friction with the Flutter team, as they have lots of stuff to do. This kind of question can get you banned, take a look at the community guidelines please.

Thank you in advance, I completely understand your points. My question was more regarding the priority of this issue and if anyone is taking care of it, as nothing was said about that and there were already some attempts on fixing this, so we don't know if this will be done this year or it will be Open for the next 5 again... :( Furthermore, since you have the Center alignment and something related, it felt like extending that to customized pixels (and not only start and center) would be Nice