问题描述
我在渲染树上遇到类似于> > Column
的渲染问题,其中最后一个Column
在PageView
的页面内.
I have a rendering issue with render tree similar to Column
>PageView
>Column
, where the last Column
is inside a page of the PageView
.
PageView
的渲染不正确,所以我得到一个异常(Horizontal viewport was given unbounded height.
),因为框架无法计算其大小,可以通过将其包装到Flexible
或,但我不希望PageView
占据整个屏幕,我希望它尽可能小并位于屏幕中央.
The PageView
isn't being rendered correctly, so I get an exception (Horizontal viewport was given unbounded height.
) as the framework can't calculate its sizes, I can fix it by wrapping it into a Flexible
or an Expanded
, but I don't want the PageView
to take the whole screen, I want it to be as small as possible and on the center on the screen.
这是我的问题的代表:
// 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
以便显示它):
This is what I wanted to achieve (I removed the PageView
in order to show it):
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'),
],
),
],
),
);
}
}
这是我可以解决的方法,但是它并不完美,我将在后面显示:
And this is how I can fix it, but it's not perfect, I will show later:
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
因子,而在我的第一个代码示例中,小部件将自动将其大小调整到屏幕中心.
This solution isn't perfect because Spacer
and Flexible
or Expanded
always try to maintain it's proportionality of the flex
weight, which means that for smaller displays the Spacer
won't vanish, it will remain there, whereas the first and desired image won't have such a void space. As we can see in the below image, the Spacer is always there. Also I have to calculate the flex
factor for every change in this design, whereas in my first code example the widget will size itself to the center of the screen automatically.
我如何指示PageView
尽可能的小,而不是尽可能地扩展,因为这是我可以在网上找到的唯一解决方案?
How can I instruct PageView
then to be as small as it can be, instead of expand as much as it wants, as that's the only solution I can find online?
推荐答案
PageView
使用SliverFillViewport
环绕给定的children
.
此SliverFillViewport
不在乎children
有多小.它只关心它可以从其父空间中占据多少空间.因此Flex
和Align
小部件都没有用.
This SliverFillViewport
doesn't care about how small the children
are. It only cares how much space it can occupy from its parent. So the Flex
and Align
widget are useless.
当前使用PageView
,除非我们进行一些计算并使用SizedBox
或ConstrainedBox
,否则很可能不可能.
Currently with PageView
, it most likely not possible unless we do some calculation and use SizedBox
or ConstrainedBox
.
我还发现了讨论
这篇关于如何使小部件尽可能小(Android中的wrap_content)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!