首页 > 解决方案 > 如何使 Widget 尽可能小(Android 中的 wrap_content)?

问题描述

我有一个类似于Column>>的渲染树的渲染问题,其中最后一个位于PageView.ColumnColumnPageView

PageView没有正确呈现,所以我得到一个异常()Horizontal viewport was given unbounded height.,因为框架无法计算它的大小,我可以通过将它包装成 aFlexible或 an来修复它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总是试图保持它与重量的比例,这意味着对于较小的显示器,它不会消失,它会保留在那里,而第一个和所需的图像不会有这样的空白空间. 如下图所示,Spacer 始终存在。此外,我必须计算此设计中每次更改的因素,而在我的第一个代码示例中,小部件将自动调整到屏幕中心。FlexibleExpandedflexSpacerflex

间隔到 UI

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

标签: flutterflutter-layout

解决方案


环绕给定的PageView用途。SliverFillViewportchildren

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

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

我也发现了这个讨论


推荐阅读