得到“水平视口被赋予无限的高度”。颤抖的TabBarView

时间:2018-08-26 06:01:46

标签: flutter flutter-layout

我正在尝试创建一个个人资料页面,其中用户信息位于顶部。然后在其下有一个用于不同视图的选项卡视图。

enter image description here

这是我当前使用的代码,当我取出InvalidArgumentError: Reshape cannot infer the missing input size for an empty tensor unless all specified input sizes are non-zero [[Node: flatten_3/Reshape = Reshape[T=DT_FLOAT, Tshape=DT_INT32, _class=["loc:@training_2/RMSprop/gradients/flatten_3/Reshape_grad/Reshape"], _device="/job:localhost/replica:0/task:0/device:GPU:0"](max_pooling2d_9/MaxPool-3-0-TransposeNCHWToNHWC-LayoutOptimizer, flatten_3/stack)]] [[Node: metrics_2/acc/Mean_1/_263 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_741_metrics_2/acc/Mean_1", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]] 时不会出错,并且如果我将TabBarView包裹在TabBarView中错误Expanded出现了。

RenderFlex children have non-zero flex but incoming height constraints are unbounded.

我确实尝试了this的变体,但无法使其正常工作。

4 个答案:

答案 0 :(得分:5)

错误说明很清楚, TabBarView没有限制的高度。父窗口小部件也没有高度限制。因此,扩展小部件将无法解决此问题。

编辑:以下解决方案适用于上述问题(带有列)。一般情况下,将ListView与shrinkWrap: true一起使用。(或其他带有rinkWrap的小部件)

有一些选择:

第一个解决方案:

使用高度限制的小部件(例如SizedBox或AspectRatio)包装父小部件(列)。然后像这样使用Expanded小部件:

child: SizedBox(
          height: 300.0,
          child: Column(
            children: <Widget>[
       .
       .
       .
              Expanded(
                child: TabBarView(
                  children: <Widget>[
                    Container(
                      height: 200.0,
                      color: Colors.grey,
                    ),
                    Container(
                      height: 200.0,
                      color: Colors.green,
                    ),
                    Container(
                      height: 200.0,
                      color: Colors.purple,
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),

第二个解决方案:

在TabBarView本身上使用诸如SizedBox或AspectRatio之类的有界小部件:

SizedBox(
            height: 300.0,
            child: TabBarView(
                children: <Widget>[
                  Container(
                    height: 200.0,
                    color: Colors.grey,
                  ),
                  Container(
                    height: 200.0,
                    color: Colors.green,
                  ),
                  Container(
                    height: 200.0,
                    color: Colors.purple,
                  ),
                ],
              ),
            ),

注意:如果高度不是静态的,您还可以动态计算高度。

答案 1 :(得分:3)

基于@Yamin的答案,我使用了下面的SizeBox来获取整页

    SizedBox.expand(
        child: TabBarView(),
      )

或其他任何大小:

SizedBox(
        height: height:MediaQuery.of(context).size.height // or every other size ,
        child: TabBarView(),
      )

答案 2 :(得分:2)

我通过在TabBar内添加Container和在TabBarView内添加Expanded来解决此问题:

DefaultTabController(
    length: 3,
    child: Column(
      children: <Widget>[
        Container(child: TabBar(..)),
        Expanded(child: TabBarView(..)),
      ],
    ),
  );

答案 3 :(得分:1)

尝试使用IndexedStack代替TabBarView

我尝试了ExpandedshrinkWrap = true,... 但是没有人可以 只是尝试示例。

示例:

class Product extends StatefulWidget {
  @override
  _ProductState createState() => _ProductState();
}

class _ProductState extends State<Product> with SingleTickerProviderStateMixin {
  TabController tabController;
  int selectedIndex = 0;

  @override
  void initState() {
    super.initState();
    tabController = TabController(length: 5, vsync: this, initialIndex: 0);
  }

  @override
  void dispose() {
    tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      initialIndex: 0,
      child: Scaffold(
        body: ListView(
          shrinkWrap: true,
          children: [
            TabBar(
         
              tabs: <Widget>[
                Tab(
                  text: 'one',
                ),
                Tab(
                  text: 'two',
                ),
                Tab(
                  text: 'three',
                ),
              ],
              controller: tabController,
              onTap: (index) {
                setState(() {
                  selectedIndex = index;
                  tabController.animateTo(index);
                });
              },
            ),
            IndexedStack(
              children: <Widget>[
                Visibility(
                  child: Text('test1'),
                  maintainState: true,
                  visible: selectedIndex == 0,
                ),
                Visibility(
                  child: Text('test2'),
                  maintainState: true,
                  visible: selectedIndex == 1,
                ),
                Visibility(
                  child: Text('test3'),
                  maintainState: true,
                  visible: selectedIndex == 2,
                ),
              ],
              index: selectedIndex,
            ),
          ],
        ),
      ),
    );
  }
}

特别感谢@arbalest