How to make child to fit height in a Row in flutter?
Asked Answered
H

4

10

I have a Row widget with the Input files and search button. And the Row is inside A Column.

enter image description here

How do I make a search button to fit the height of the row, Making the button size equal to the Input field height?

I Tried adding crossAxisAlignment: CrossAxisAlignment.stretch, to the Row but getting the error:-

BoxConstraints forces an infinite height.

I don't have the height of the input field. And not want to hardcode the height of the button as it should always match the height of the Input box.

Also, Assigning the height to the Row and adding CrossAxisAlignment.stretch does not change the height of the Input Field, the only button is changing.

What is the issue here and how to fix this?

Row(
  // crossAxisAlignment: CrossAxisAlignment.stretch,
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
    Expanded(
      child: Container(
        child: TextField(
          decoration: InputDecoration(
            border: InputBorder.none,
            hintText: 'search',
            hintStyle:
                Theme.of(context).textTheme.bodyText2.copyWith(
                  color: Theme.of(context).accentColor,
                ),
            contentPadding: EdgeInsets.symmetric(
              vertical: 8, horizontal: 20
            ),
            fillColor: Theme.of(context).primaryColor,
            filled: true,
          ),
          style: Theme.of(context).textTheme.bodyText2,
        ),
      ),
    ),
    FlatButton(
      onPressed: () {},
      color: Colors.grey,
      child: Icon(
        Icons.search,
      ),
    ),
  ],
)
Hyperaemia answered 20/8, 2020 at 14:52 Comment(0)
G
17

You can wrap the row in an IntrinsicHeight with the Row having a crossAxisAlignment of CrossAxisAlignment.strech. For example:

IntrinsicHeight(
  child: Row(
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: [TextField(..), TextButton(..)],
  ),
),
Gerstner answered 16/3, 2022 at 4:17 Comment(0)
B
6

I had same requirement - I wanted to have square Container on the end of the TextField. But since text size and therefore text input height might change over time, I didn't wanted to hardcode its size.

One solution is to simply use suffixIcon on TextField as part of the text input (red square).

In my case, I had to use extra Widget outside of the TextField. The key here is to use:

  1. IntrinsicHeight as Row parent
  2. AspectRatio 1 as parent of the Container (grey square).

See code:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Demo Home Page'),
        ),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            IntrinsicHeight(
              child: Row(
                children: [
                  Expanded(
                    child: TextField(
                      textAlignVertical: TextAlignVertical.center,
                      decoration: InputDecoration(
                        hintText: "Search...",
                        filled: true,
                        fillColor: Colors.blueGrey,
                        border: InputBorder.none,
                        prefixIcon: const Icon(
                          Icons.search,
                          color: Colors.white,
                        ),
                        suffixIcon: Container(
                          color: Colors.red,
                          child: const Icon(
                            Icons.close,
                            color: Colors.black,
                          ),
                        ),
                      ),
                    ),
                  ),
                  AspectRatio(
                    aspectRatio: 1,
                    child: GestureDetector(
                      onTap: () {
                        // handle on tap here
                      },
                      child: Container(
                        color: Colors.grey,
                        child: const Icon(
                          Icons.clear,
                          color: Colors.white,
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

And see image.

Note, I found the inspiration for this solution in this SO answer.

Burned answered 6/11, 2020 at 18:28 Comment(1)
This should be accepted answer as you can't always set a constant heigthBree
S
0

I could give you an idea.
Wrap the FlatButton too, within Container, and define width and height for those. Something like this,

    Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Container(
              width: MediaQuery.of(context).size.width * 0.8,
              color: Theme.of(context).primaryColor,
              height: 50.0,
              child: TextField(
                decoration: InputDecoration(
                  border: InputBorder.none,
                  hintText: 'search',
                  hintStyle: Theme.of(context).textTheme.bodyText2.copyWith(
                        color: Theme.of(context).accentColor,
                      ),
                  contentPadding:
                      EdgeInsets.symmetric(vertical: 8, horizontal: 20),
                  filled: true,
                ),
                style: Theme.of(context).textTheme.bodyText2,
              ),
            ),
            Container(
              height: 50.0,
              width: MediaQuery.of(context).size.width * 0.2,
              child: FlatButton(
                onPressed: () {},
                color: Colors.grey,
                child: Icon(
                  Icons.search,
                ),
             ),
           ),
       ],
    )

enter image description here
Or else, at least define height and width for FlatButton and leave the TextField to be Expanded.

Hope that works!

Saccharin answered 20/8, 2020 at 15:3 Comment(2)
It is not working, with this hight of the button didn't change but width is not half of the total width.Hyperaemia
Sort of, height 50 is almost perfect guess for the input size, but if you specify height other than 50, say 100, we have the same problem.Hyperaemia
P
-1

To have the Button always have the same height as the TextField it would be ideal to wrap the Row widget with a container with a fixed height and the Button with a Container with and double.infinity height:

Container(
  height: 48,
  child: Row(
    // crossAxisAlignment: CrossAxisAlignment.stretch,
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      Expanded(
        child: Container(
          child: TextField(
            decoration: InputDecoration(
              border: InputBorder.none,
              hintText: 'search',
              hintStyle:
              Theme.of(context).textTheme.bodyText2.copyWith(
                color: Theme.of(context).accentColor,
              ),
              contentPadding: EdgeInsets.symmetric(
                vertical: 8, horizontal: 20
              ),
              fillColor: Theme.of(context).primaryColor,
              filled: true,
            ),
            style: Theme.of(context).textTheme.bodyText2,
          ),
        ),
      ),
      Container(
        height: double.infinity,
        child: FlatButton(
          onPressed: () {},
          color: Colors.grey,
          child: Icon(
            Icons.search,
          ),
        ),
      ),
    ],
  ),
);
Pigmentation answered 20/8, 2020 at 15:20 Comment(1)
What height would you give to the Row(), here again, you have to guess the height of Input Box.Hyperaemia

© 2022 - 2024 — McMap. All rights reserved.