我有类似于 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
不会消失,它会保留在那里,而第一个和所需的图像不会有这样的虚空。正如我们在下图中所见,Spacer 始终存在。此外,我必须为这个设计中的每一个变化计算 flex
因子,而在我的第一个代码示例中,小部件将自动调整到屏幕中心的大小。我怎样才能指示
PageView
尽可能小,而不是尽可能多地扩展,因为这是我可以在网上找到的唯一解决方案? 最佳答案
PageView
使用 SliverFillViewport
来环绕给定的 children
。
这个 SliverFillViewport
并不关心 children
有多小。它只关心它可以从父级那里占据多少空间。所以 Flex
和 Align
小部件没用。
目前使用 PageView
,除非我们进行一些计算并使用 SizedBox
或 ConstrainedBox
,否则很可能不可能。
我也发现了这个 discussion
关于flutter - 如何使 Widget 尽可能小(Android 中的 wrap_content)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59294421/