调整父小部件的大小以适应 Flutter 中的子帖子“变换”
Posted
技术标签:
【中文标题】调整父小部件的大小以适应 Flutter 中的子帖子“变换”【英文标题】:Resizing parent widget to fit child post 'Transform' in Flutter 【发布时间】:2020-09-23 09:28:03 【问题描述】:我在 Flutter 中使用 Transforms
创建一个滚动轮播,用于从各种选项中进行选择。
这使用了诸如ListView.builder
之类的标准元素,除了Transform 的父小部件没有按比例缩小以适应此处所示的内容之外,这些元素都可以正常工作:
这是用于生成“卡片”的代码(实际上里面有一张卡片,但我已经把它去掉了,试图让所有东西都能正确缩放):
return Align(
child: Transform(
alignment: Alignment.center,
transform: mat,
child: Container(
height: 220,
color: color,
width: MediaQuery.of(context).size.width * 0.7,
child: Text(
offset.toString(),
style: TextStyle(color: Colors.white, fontSize: 12.0),
),
),
),
);
即使我删除了 Container 的“height”参数(因此所有内容都可以缩放以适合“Text”小部件),包含 Transform
小部件的框周围仍然有间隙。
Flutter 似乎没有任何文档来说明如果其中的对象被转换,如何重新缩放父级 - 这里的任何人都知道或知道解决方法吗?
编辑:从此返回的小部件在有状态小部件的build
小部件中使用。堆栈是 Column > Container > ListView.builder。
如果我删除变换,容器会按照我的意愿组合在一起 - 似乎对容器执行透视变换会“缩小”它的内容(在这种情况下,颜色 - 检查链接的屏幕抓取),但是不会重新缩放容器本身,这是我想要实现的。
【问题讨论】:
什么是父小部件,您将整个代码返回到哪里? 感谢@Chinky 添加图片。由于我目前的评分,我不能。 @BigRedSwitch 与评分无关,只需在图片链接前加一个“!”即可:D @Chinky Sight - 我试过了。拒绝! D-: 您找到解决方案了吗?遇到了完全相同的问题,不明白为什么“setState”不会让 Listview.builder 重新计算转换后的瓷砖的高度 【参考方案1】:对此我有一个棘手的解决方案:addPostFrameCallback + 覆盖。
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
// ignore: must_be_immutable
class ChildSizeWidget extends HookWidget
final Widget Function(BuildContext context, Widget child, Size size) builder;
final Widget child;
final GlobalKey _key = GlobalKey();
OverlayEntry _overlay;
ChildSizeWidget( this.child, this.builder );
@override
Widget build(BuildContext context)
final size = useState<Size>(null);
useEffect(()
WidgetsBinding.instance.addPostFrameCallback((timestamp)
_overlay = OverlayEntry(
builder: (context) => Opacity(
child: SingleChildScrollView(
child: Container(
child: child,
key: _key,
),
),
opacity: 0.0,
),
);
Overlay.of(context).insert(_overlay);
WidgetsBinding.instance.addPostFrameCallback((timestamp)
size.value = _key.currentContext.size;
_overlay.remove();
);
);
return () => null;
, [child]);
if (size == null || size.value == null)
return child;
else
return builder(context, child, size.value);
用法:
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
class HomeView extends HookWidget
@override
Widget build(BuildContext context)
final change = useState<bool>(false);
final normal = Container(
color: Colors.blueAccent,
height: 200.0,
width: 200.0,
);
final big = Container(
color: Colors.redAccent,
height: 300.0,
width: 200.0,
);
return Column(
children: [
Container(
alignment: Alignment.center,
child: ChildSizeWidget(
child: change.value ? big : normal,
builder: (context, child, size) => AnimatedContainer(
alignment: Alignment.center,
child: SingleChildScrollView(child: child),
duration: Duration(milliseconds: 250),
height: size.height,
),
),
color: Colors.grey,
),
FlatButton(
child: Text('Toggle child'),
onPressed: () => change.value = !change.value,
color: Colors.green,
),
],
);
我有一个包含多个选项的菜单,它们有不同的高度,在动画的帮助下,这没关系,它对我来说真的很好。
【讨论】:
【参考方案2】:你为什么要使用对齐,正如我在你的代码中看到的那样,没有设置或使用属性来对齐任何东西。因此,请尝试移除 Transform 周围的 Align 小部件。 因为根据文档,Transform 是这样一个小部件,它试图与他们的孩子一样大小。这样就可以满足你的要求了。
有关更多信息,请查看此文档:https://flutter.dev/docs/development/ui/layout/box-constraints
希望对你有帮助!
【讨论】:
对齐只是为了防止父小部件在整个屏幕上缩放。它与这里的问题并不真正相关。我已经尝试删除它 - 没有任何区别。有关详细信息,请参阅上面的“编辑”。以上是关于调整父小部件的大小以适应 Flutter 中的子帖子“变换”的主要内容,如果未能解决你的问题,请参考以下文章
如何在 AppBar 中包装子小部件以获得更大的子高度和 Flutter 中的填充