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

mFe*_*ein 3 flutter flutter-layout

我有类似于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'),
                ],
              ),
            ],
          ),
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

这就是我想要实现的(我删除了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'),
            ],
          ),
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

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

灵活/扩展的解决方案

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,),
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

这个方案并不完美,因为SpacerFlexibleExpanded总是试图保持它的相称的flex重量,这意味着较小的显示Spacer不会消失,它会留在那里,而第一和所需的图像不会有这样的空隙空间. 正如我们在下图中所见,Spacer 始终存在。此外,我必须计算flex此设计中每次更改的系数,而在我的第一个代码示例中,小部件将自动调整到屏幕中心。

间隔进入 UI

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

Cra*_*Cat 5

环绕给定的PageView用途。SliverFillViewportchildren

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

目前PageView,除非我们进行一些计算和使用SizedBoxor ,否则很可能不可能ConstrainedBox

我也发现了这个讨论