我想通过使用其内容(子项)的首选和/或继承高度来影响其
BottomAppBar
来调整 height
的大小。
我需要这样做来减少
code duplication
并可能使以后更容易 maintain the code
基础。我有一个大约 9 个步骤的向导,其中一些按钮可能会有所不同,这意味着如果我不想出现溢出错误,我需要手动为 BottomAppBar
小部件分配高度值。
flutter 中 BottomNavBar 小部件的当前文档:
/// The double value used to indicate the height of the [BottomAppBar].
/// If this is null, the default value is the minimum in relation to the content,
/// unless [ThemeData.useMaterial3] is true, in which case it defaults to 80.0.
/// final double? height;
由于材质3,它使用材质3中定义的首选尺寸,大约为80。这意味着如果它为空或没有向小部件提供高度,则默认为该尺寸。因此,它无法动态调整大小,因为材料 3 限制了它这样做。
尝试过动态调整小部件大小的 3 个选项,据我现在了解,由于限制而无法发生:
LayoutBuilder
IntrinsicHeight
MediaQuery
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
TLoggerHelper.info(constraints.toString());
return BottomAppBar(
child: Container(
color: Theme.of(context).bottomAppBarTheme.color,
child: Column(
crossAxisAlignment: expand == true
? CrossAxisAlignment.stretch
: centerContent == false
? CrossAxisAlignment.start
: CrossAxisAlignment.center,
children: [
/// App footer
showMsaText == true
? const Column(
children: [
TAppFooter(),
SizedBox(height: TSizes.spaceBtwItemsSm),
],
)
: const SizedBox.shrink(),
/// Bottom Nav content
if (button != null)
button!
else if (bottomNavBarContent != null)
bottomNavBarContent!(context)
],
),
),
);
},
);
约束输出: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=914.3)
该约束仅具有物理屏幕的最大宽度和高度,而不是底部应用程序必须占用的空间才能呈现其所有子项而不会出现溢出问题。
正如前面提到的
BottomAppBar
本身,如果没有给出高度,则会导致空高度,默认为指定的标准化高度 80。
IntrinsicHeight 应该可以工作,因为它预先计算了子级的trinsicHeight 并将其分配给容器。
我使用 MediaQuery.of(context).size.height 和乘数将高度传递给自定义组件,以提供动态大小调整。
这可以工作,但同样,它涉及分配给底部导航栏的静态值。我不知道运行时高度是多少。我只是近似它,字面上看它。
我能想到的唯一两个解决方案是坚持媒体查询并为底部导航栏分配动态计算的静态高度。
或者,创建我自己的具有容器的自定义小部件,该容器应该支持使用intrinsicHeight。
如果你们中有人遇到同样的问题,我很想听听你们是如何解决的。有什么更优雅的方法来解决这个问题?
提前谢谢你:)
动态底部导航小部件
class DynamicBottomAppBar extends StatelessWidget implements PreferredSizeWidget {
final Widget child;
final double defaultHeight;
DynamicBottomAppBar({required this.child, this.defaultHeight = 80.0});
@override
Size get preferredSize {
final childHeight = _calculateChildHeight();
return Size.fromHeight(childHeight ?? defaultHeight);
}
double? _calculateChildHeight() {
final renderBox = child.key != null
? (child.key as GlobalKey).currentContext?.findRenderObject() as RenderBox?
: null;
return renderBox?.size.height;
}
@override
Widget build(BuildContext context) {
return BottomAppBar(
child: Container(
color: Theme.of(context).bottomAppBarTheme.color,
child: child,
),
);
}
}
这就是你可以使用的方式
Widget build(BuildContext context) {
return DynamicBottomAppBar(
child: Column(
children: [
// Add your dynamic content here
showMsaText ? const TAppFooter() : const SizedBox.shrink(),
if (button != null) button! else if (bottomNavBarContent != null) bottomNavBarContent!(context),
],
),
);
}