Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

proper way to get widget height in SafeArea

People also ask

How do you get the available height in flutter?

To get the size/position of a widget on screen, you can use GlobalKey to get its BuildContext to then find the RenderBox of that specific widget, which will contain its global position and rendered size.

How do you find the height of a child Widget widget flutter?

There is no direct way to calculate the size of the widget, so to find that we have to take the help of the context of the widget. Calling context. size returns us the Size object, which contains the height and width of the widget.


I know that there is right answer, but maybe someone is looking for safe area height, not height of safe area widget child, but only safe area top padding:

var safePadding = MediaQuery.of(context).padding.top;

You can always use LayoutBuilder for such cases.

child: SafeArea(
        child: new LayoutBuilder(
            builder: (BuildContext context, BoxConstraints constraints) {
              // constraints variable has the size info
              return Container();
            }
        ),
      ),

for more info: https://www.youtube.com/watch?v=IYDVcriKjsw


Flutter 2.5

Add this at top level of Widget...and you can get exact SafeArea height.

final availableHeight = MediaQuery.of(context).size.height -
    AppBar().preferredSize.height -
    MediaQuery.of(context).padding.top -
    MediaQuery.of(context).padding.bottom;

to get the size of the SafeArea, you need to encapsulate inside a LayoutBuilder , and use constraints.maxHeight

look at your own example modified:

I/flutter (20405): full Screen height: 683.4285714285714
I/flutter (20405): Screen height: 683.4285714285714
I/flutter (20405): Real safe height: 659.4285714285714

class _MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(body: _Body()),
    );
  }
}

class _Body extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print('full Screen height: ${MediaQuery.of(context).size.height}');
    return Container(
      constraints: BoxConstraints.expand(),
      decoration: BoxDecoration(color: Colors.red),
      child: SafeArea(
        child: _SafeHeightWidget(),
      ),
    );
  }
}

class _SafeHeightWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        print('Screen height: ${MediaQuery.of(context).size.height}');
        print('Real safe height: ${constraints.maxHeight}');
        return Container(
          color: Colors.lightBlue,
        );
      },
    );
  }
}

Flutter 2.5

Had a similar challenge.

Learned the hard way:

Do not wrap SafeArea inside main.dart application, instead wrap your Scaffold with SafeArea Widget (even better create a ReusableScaffold with wrapped SafeArea) and then you can extract the MediaQuery height with SafeArea below code:

var availableHeight = MediaQuery.of(context).size.height -
    AppBar().preferredSize.height -
    MediaQuery.of(context).padding.top -
    MediaQuery.of(context).padding.bottom;

The trick is if your whole main.app child is wrapped with SafeArea the padding.top and padding.bottom will always remain 0 because that's how SafeArea works - it makes padding EdgeInsets.zero - you can find this information inside SafeArea documentation.

But if you calculate the height without wrapping safeArea you will get the padding of top & bottom which allows to get the remaining height without SafeArea

example:

I/flutter (12472): full height 712.0 -> full height
I/flutter (12472): available height 618.5 -> remaining height minus safeArea & appBar
I/flutter (12472): MediaQuery.of(context).padding.top 37.5 -> safeArea height
I/flutter (12472): MediaQuery.of(context).padding.bottom 0.0 -> Im using android with 720 height, on iPhone X it would not zero
I/flutter (12472): viewPadding EdgeInsets(0.0, 37.5, 0.0, 0.0) -> shows all padding insets