rahul  Kushwaha
rahul Kushwaha

Reputation: 2809

How to make child to fit height in a Row in flutter?

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,
      ),
    ),
  ],
)

Upvotes: 10

Views: 11550

Answers (4)

masterwok
masterwok

Reputation: 5131

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(..)],
  ),
),

Upvotes: 20

Matej Hlatky
Matej Hlatky

Reputation: 600

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.

Upvotes: 7

Shri Hari L
Shri Hari L

Reputation: 4894

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!

Upvotes: 0

J. S.
J. S.

Reputation: 9625

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,
          ),
        ),
      ),
    ],
  ),
);

Upvotes: -1

Related Questions