我有类似于 Column > PageView > Column 的渲染树的渲染问题,其中最后一个 Column 位于 PageView 的页面内。
PageView 未正确呈现,因此我收到一个异常 ( Horizontal viewport was given unbounded height. ),因为框架无法计算其大小,我可以通过将其包装到 FlexibleExpanded 中来修复它,但我不希望 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 以显示它):

flutter - 如何使 Widget 尽可能小(Android 中的 wrap_content)?-LMLPHP
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'),
            ],
          ),
        ],
      ),
    );
  }
}

这就是我可以修复它的方法,但它并不完美,我稍后会展示:

flutter - 如何使 Widget 尽可能小(Android 中的 wrap_content)?-LMLPHP
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,),
        ],
      ),
    );
  }
}

这个解决方案并不完美,因为 SpacerFlexibleExpanded 总是试图保持它与 flex 权重的比例,这意味着对于较小的显示器,Spacer 不会消失,它会保留在那里,而第一个和所需的图像不会有这样的虚空。正如我们在下图中所见,Spacer 始终存在。此外,我必须为这个设计中的每一个变化计算 flex 因子,而在我的第一个代码示例中,小部件将自动调整到屏幕中心的大小。

flutter - 如何使 Widget 尽可能小(Android 中的 wrap_content)?-LMLPHP

我怎样才能指示 PageView 尽可能小,而不是尽可能多地扩展,因为这是我可以在网上找到的唯一解决方案?

最佳答案

PageView 使用 SliverFillViewport 来环绕给定的 children

这个 SliverFillViewport 并不关心 children 有多小。它只关心它可以从父级那里占据多少空间。所以 FlexAlign 小部件没用。

目前使用 PageView ,除非我们进行一些计算并使用 SizedBoxConstrainedBox ,否则很可能不可能。

我也发现了这个 discussion

关于flutter - 如何使 Widget 尽可能小(Android 中的 wrap_content)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59294421/

10-10 02:24