我的渲染树存在类似于 Column
的渲染问题> PageView
> Column
,最后一个 Column
位于 PageView
的页面内.
PageView
没有正确渲染,所以我得到一个异常( Horizontal viewport was given unbounded height.
),因为框架无法计算其大小,我可以通过将其包装到 Flexible
来修复它。或Expanded
,但我不想要PageView
为了占据整个屏幕,我希望它尽可能小并位于屏幕的中心。
这是我的问题的描述:
// This code throws an exception:
class Widget_1_Has_Problem extends StatelessWidget {
final PageController pageController = PageController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.done,size: 112),
SizedBox(height: 32),
PageView(
physics: NeverScrollableScrollPhysics(),
controller: pageController,
children: <Widget>[
// Many widgets go here, I am just simplifying with a Column.
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text('TEXT TEXT TEXT TEXT TEXT TEXT'),
SizedBox(height: 16),
Text('TEXT2 TEXT2 TEXT2 TEXT2 TEXT2 TEXT2'),
],
),
],
),
],
),
);
}
}
这就是我想要实现的目标(我删除了 PageView
以显示它):
class Widget_2_No_PageView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.done,size: 112),
SizedBox(height: 32),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text('TEXT TEXT TEXT TEXT TEXT TEXT'),
SizedBox(height: 16),
Text('TEXT2 TEXT2 TEXT2 TEXT2 TEXT2 TEXT2'),
],
),
],
),
);
}
}
这就是我可以修复它的方法,但它并不完美,我稍后会展示:
class Widget_3_With_Flex_Not_Perfect_Solution extends StatelessWidget {
final PageController pageController = PageController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Spacer(flex: 2,),
Icon(Icons.done,size: 112),
SizedBox(height: 32),
Flexible(
flex: 1,
child: PageView(
physics: NeverScrollableScrollPhysics(),
controller: pageController,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text('TEXT TEXT TEXT TEXT TEXT TEXT'),
SizedBox(height: 16),
Text('TEXT2 TEXT2 TEXT2 TEXT2 TEXT2 TEXT2'),
],
),
],
),
),
Spacer(flex: 2,),
],
),
);
}
}
此解决方案并不完美,因为 Spacer
和Flexible
或Expanded
始终尝试保持 flex
的比例重量,这意味着对于较小的显示器来说 Spacer
不会消失,它会保留在那里,而第一个和所需的图像不会有这样的空白空间。如下图所示,垫片始终存在。我还必须计算 flex
影响此设计中每个更改的因素,而在我的第一个代码示例中,小部件将自动将其自身调整到屏幕中心。
我该如何指导PageView
然后尽可能小,而不是随心所欲地扩展,因为这是我在网上可以找到的唯一解决方案?
最佳答案
PageView
使用SliverFillViewport
来环绕给定的子项
。
这个SliverFillViewport
并不关心子项
有多小。它只关心它可以从父级占据多少空间。因此 Flex
和 Align
小部件没有用。
目前使用 PageView
,这很可能是不可能的,除非我们进行一些计算并使用 SizedBox
或 ConstrainedBox
。
我还发现了这个discussion
关于flutter - 如何让一个Widget尽可能小(Android中的wrap_content)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59294421/