flutter 在SafeArea中获取微件高度的正确方法

gopyfrb3  于 2023-02-13  发布在  Flutter
关注(0)|答案(5)|浏览(353)

我尝试获取小部件的高度,但打印的值相同

I/flutter (19253): full height: 976.0
I/flutter (19253): safe height: 976.0

我猜第二个值应该更小,因为容器放置在状态栏下面。我做错了什么?我需要高度,因为在这个容器中将是Wrap小工具(实际上是ReorderableWrap https://pub.dartlang.org/packages/reorderables#-readme-tab-)与36卡,3行12卡和卡的高度必须是其容器的1/3。
我没有找到好的可重新排序的网格。但无论如何,我的问题是,为什么一个容器在一个安全的区域有相同的高度容器,填补了整个屏幕?

import 'package:flutter/material.dart';

void main() {
  runApp(_MyApp());
}

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 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) {
    print('safe height: ${MediaQuery.of(context).size.height}');
    return Container(
      color: Colors.lightBlue,
    );
  }
}
fxnxkyjh

fxnxkyjh1#

如果您只需要安全区域顶部填充,而不需要安全区域子构件的高度:

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

oprakyz72#

在这种情况下,您可以始终使用LayoutBuilder

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

有关详细信息:https://www.youtube.com/watch?v=IYDVcriKjsw

ni65a41a

ni65a41a3#

Flutter2.5

添加到窗口小部件的顶层...你可以得到确切的安全区高度。

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

hts6caw34#

    • Flutter2.5**

有过类似的挑战。
从惨痛的教训中得知:

    • 不要在main. dart应用程序中 Package SafeArea,**而是使用SafeArea Widget Package 您的Scaffold(更好的方法是使用 Package 的SafeArea创建一个ReusableScaffold),然后您可以使用SafeArea提取MediaQuery高度,代码如下:
var availableHeight = MediaQuery.of(context).size.height -
    AppBar().preferredSize.height -
    MediaQuery.of(context).padding.top -
    MediaQuery.of(context).padding.bottom;

诀窍在于,如果您的整个www.example.com子进程都用SafeArea Package ,则 * padding. top * 和 * padding. bottom * 将始终保持为0,因为这就是SafeArea的工作方式-它使填充www.example.com-您可以在SafeArea文档中找到此信息。 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.
但是如果你计算高度而不 Package safeArea,你会得到顶部和底部的填充,这允许得到剩余的高度没有safeArea
示例:

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
qrjkbowd

qrjkbowd5#

要获得SafeArea的大小,需要封装到LayoutBuilder中,并使用constraints.maxHeight
看看你自己的例子修改:
I/扑动(20405):全屏高度:683.4285714285714
I/扑动(20405):屏幕高度:683.4285714285714
I/扑动(20405):真实的安全高度: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,
        );
      },
    );
  }
}

相关问题