TabBar中的TabBarView会占用剩余空间

时间:2019-05-22 09:15:33

标签: dart flutter uitabbar

我一直在我的flapp应用程序中使用TabBar(),除非我发现TabBarView()在屏幕尺寸变化时弄乱了它,否则它将一直有效。 跟踪this问题后,我发现问题的解决方案是Expanded()对于TabBarView()。我已经尽了最大的努力,但是我得到的只是关于渲染数据的很多错误。

       ⡿flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following assertion was thrown during performLayout():
flutter: RenderFlex children have non-zero flex but incoming height constraints are unbounded.
       ⣟flutter: When a column is in a parent that does not provide a finite height constraint, for example if it is
flutter: in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
flutter: flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
flutter: space in the vertical direction.
flutter: These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
flutter: cannot simultaneously expand to fit its parent.
flutter: Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible
flutter: children (using Flexible rather than Expanded). This will allow the flexible children to size
flutter: themselves to less than the infinite remaining space they would otherwise be forced to take, and
flutter: then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum
flutter: constraints provided by the parent.
flutter: If this message did not help you determine the problem, consider using debugDumpRenderTree():
flutter:   https://flutter.dev/debugging/#rendering-layer
flutter:   http://docs.flutter.io/flutter/rendering/debugDumpRenderTree.html
flutter: The affected RenderFlex is:
flutter:   RenderFlex#bc077 relayoutBoundary=up2 NEEDS-LAYOUT NEEDS-PAINT(creator: Column ← TabWidget ← Column ← MediaQuery ← LayoutId-[<_ScaffoldSlot.body>] ← CustomMultiChildLayout ← AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ← _InkFeatures-[GlobalKey#4f100 ink renderer] ← NotificationListener<LayoutChangedNotification> ← PhysicalModel ← ⋯, parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size), constraints: BoxConstraints(w=375.0, 0.0<=h<=Infinity), size: MISSING, direction: vertical, mainAxisAlignment: start, mainAxisSize: min, crossAxisAlignment: start, textDirection: ltr, verticalDirection: down)
flutter: The creator information is set to:
flutter:   Column ← TabWidget ← Column ← MediaQuery ← LayoutId-[<_ScaffoldSlot.body>] ←
flutter:   CustomMultiChildLayout ← AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ←
flutter:   _InkFeatures-[GlobalKey#4f100 ink renderer] ← NotificationListener<LayoutChangedNotification> ←
flutter:   PhysicalModel ← ⋯
flutter: The nearest ancestor providing an unbounded width constraint is: RenderFlex#0807f relayoutBoundary=up1 NEEDS-LAYOUT NEEDS-PAINT:
flutter:   creator: Column ← MediaQuery ← LayoutId-[<_ScaffoldSlot.body>] ← CustomMultiChildLayout ←
flutter:     AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ← _InkFeatures-[GlobalKey#4f100 ink
flutter:     renderer] ← NotificationListener<LayoutChangedNotification> ← PhysicalModel ←
flutter:     AnimatedPhysicalModel ← Material ← ⋯
flutter:   parentData: offset=Offset(0.0, 0.0); id=_ScaffoldSlot.body (can use size)
flutter:   constraints: BoxConstraints(0.0<=w<=375.0, 0.0<=h<=591.0)
flutter:   size: MISSING
flutter:   direction: vertical
flutter:   mainAxisAlignment: start
flutter:   mainAxisSize: min
flutter:   crossAxisAlignment: stretch
flutter:   verticalDirection: down
flutter: See also: https://flutter.dev/layout/
flutter: If none of the above helps enough to fix this problem, please don't hesitate to file a bug:
flutter:   https://github.com/flutter/flutter/issues/new?template=BUG.md
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0      RenderFlex.performLayout.<anonymous closure> (package:flutter/src/rendering/flex.dart:691:11)
flutter: #1      RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:717:10)
flutter: #2      RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #3      RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:743:15)
flutter: #4      RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #5      MultiChildLayoutDelegate.layoutChild (package:flutter/src/rendering/custom_layout.dart:142:11)
flutter: #6      _ScaffoldLayout.performLayout (package:flutter/src/material/scaffold.dart:443:7)
flutter: #7      MultiChildLayoutDelegate._callPerformLayout (package:flutter/src/rendering/custom_layout.dart:212:7)
flutter: #8      RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:356:14)
flutter: #9      RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #10     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #11     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #12     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #13     _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1214:11)
flutter: #14     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #15     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #16     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #17     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #18     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #19     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #20     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #21     RenderStack.performLayout (package:flutter/src/rendering/stack.dart:510:15)
flutter: #22     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #23     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #24     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #25     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #26     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #27     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #28     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #29     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #30     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #31     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #32     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #33     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #34     RenderOffstage.performLayout (package:flutter/src/rendering/proxy_box.dart:3067:13)
flutter: #35     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #36     RenderStack.performLayout (package:flutter/src/rendering/stack.dart:510:15)
flutter: #37     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #38     __RenderTheatre&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #39     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #40     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #41     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #42     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #43     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #44     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #45     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #46     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #47     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #48     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
flutter: #49     RenderObject.layout (package:flutter/src/rendering/object.dart:1620:7)
flutter: #50     RenderView.performLayout (package:flutter/src/rendering/view.dart:151:13)
flutter: #51     RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1497:7)
flutter: #52     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:766:18)
flutter: #53     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:346:19)
flutter: #54     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:701:13)
flutter: #55     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:285:5)
flutter: #56     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1012:15)
flutter: #57     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:952:9)
flutter: #58     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:773:7)
flutter: #60     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:382:19)
flutter: #61     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:416:5)
flutter: #62     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:171:12)
flutter: (elided one frame from package dart:async-patch)
flutter:
flutter: The following RenderObject was being processed when the exception was fired: RenderFlex#bc077 relayoutBoundary=up2 NEEDS-LAYOUT NEEDS-PAINT:
flutter:   creator: Column ← TabWidget ← Column ← MediaQuery ← LayoutId-[<_ScaffoldSlot.body>] ←
flutter:     CustomMultiChildLayout ← AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ←
flutter:     _InkFeatures-[GlobalKey#4f100 ink renderer] ← NotificationListener<LayoutChangedNotification> ←
flutter:     PhysicalModel ← ⋯
       ⣯flutter:   parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size)
flutter:   constraints: BoxConstraints(w=375.0, 0.0<=h<=Infinity)
flutter:   size: MISSING
flutter:   direction: vertical
flutter:   mainAxisAlignment: start
flutter:   mainAxisSize: min
flutter:   crossAxisAlignment: start
flutter:   textDirection: ltr
flutter:   verticalDirection: down
flutter: This This RenderObject had the following descendants (showing up to depth 5):
flutter:     child 1: RenderPadding#ec776 relayoutBoundary=up3 NEEDS-PAINT
flutter:       child: RenderDecoratedBox#82c7d relayoutBoundary=up4 NEEDS-PAINT
flutter:         child: RenderPadding#47def relayoutBoundary=up5 NEEDS-PAINT
flutter:           child: RenderCustomPaint#d3174 relayoutBoundary=up6 NEEDS-PAINT
flutter:             child: _TabLabelBarRenderer#1dbbb relayoutBoundary=up7 NEEDS-PAINT
flutter:     child 2: _RenderScrollSemantics#ab273 NEEDS-LAYOUT NEEDS-PAINT
flutter:       child: RenderPointerListener#85f41 NEEDS-LAYOUT NEEDS-PAINT
flutter:         child: RenderSemanticsGestureHandler#dfb17 NEEDS-LAYOUT NEEDS-PAINT
flutter:           child: RenderPointerListener#36472 NEEDS-LAYOUT NEEDS-PAINT
flutter:             child: RenderSemanticsAnnotations#0d0f0 NEEDS-LAYOUT NEEDS-PAINT
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
flutter: Another exception was thrown: RenderBox was not laid out: RenderFlex#bc077 relayoutBoundary=up2 NEEDS-PAINT
flutter: Another exception was thrown: RenderBox was not laid out: RenderFlex#0807f relayoutBoundary=up1 NEEDS-PAINT
flutter: Another exception was thrown: NoSuchMethodError: The method '>' was called on null.

现在让您了解我一直在做的事情,我有一个小部件类,其中定义了TabBar,并且在不同的地方使用它。

这是我的TabBar类的小部件:

@override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Container(
          margin: EdgeInsets.only(left: 16.0, right: 16.0),
          decoration: BoxDecoration(
            color: Colors.white.withOpacity(0.0),
            border: Border(bottom: BorderSide(color: Colors.grey, width: 0.5))),
          child: TabBar(
            unselectedLabelColor: Colors.grey,
            unselectedLabelStyle: TextStyle().copyWith(fontSize: 16.0, fontWeight: FontWeight.normal),
            labelColor: Color.fromRGBO(253, 92, 99, 1),
            labelStyle: TextStyle().copyWith(fontSize: 16.0, fontWeight: FontWeight.bold),
            indicatorColor: Color.fromRGBO(253, 92, 99, 1),
            indicatorWeight: widget.indicatorWeight,
            controller: _controller,
            tabs: [
              new Tab(
                child: Padding(
                  padding: EdgeInsets.only(top: 18.0),
                  child: Text(widget.childOneHeader, style: TextStyle(fontSize: 15.0)),
                )
              ),
              new Tab(
                child: Padding(
                  padding: EdgeInsets.only(top: 18.0),
                  child: Text(widget.childTwoHeader, style: TextStyle(fontSize: 15.0)),
                )
              ),
              new Tab(
                child: Padding(
                  padding: EdgeInsets.only(top: 18.0),
                  child: Text(widget.childThreeHeader, style: TextStyle(fontSize: 15.0)),
                )
              )
            ]
          )
        ),
        Expanded(
          //height: widget.layoutHeight,
          child: new TabBarView(
            controller: _controller,
            children: <Widget>[
              widget.childOne,
              widget.childTwo,
              widget.childThree
            ],
          )
        )
      ]
    );

带有widget.的数据来自其构造函数。

现在,我一直在页面ListView()中使用TabBarView() children来使用它,所以我只从他们那里传递了它。

使用TabBar代码的类:

body: Column(
   mainAxisSize: MainAxisSize.min,
   crossAxisAlignment: CrossAxisAlignment.stretch,
   children: <Widget>[
     Text('Heading'),
     Container(),
     TabWidget(
            indicatorWeight: 1.0,
            childOneHeader: 'Title 1',
            childTwoHeader: 'Title 2',
            childThreeHeader: 'Title 3',
            childOne: ListView(
              shrinkWrap: true,
              scrollDirection: Axis.vertical,
              children: this.isDataNull ? 
                [Container(
                  child: errorWidget,
                )] 
                : this.getOffersWidgets()
            ),
            childTwo: ListView(
              shrinkWrap: true,
              scrollDirection: Axis.vertical,
              children: this.isDataNull ? 
              [Container(
                child: errorWidget,
              )] 
              : this.getBarWidgets()
            ),
            childThree: ListView(
              shrinkWrap: true,
              scrollDirection: Axis.vertical,
              children: this.isDataNull ? 
              [Container(
                child: errorWidget,
              )]
              : this.getEventWidget()
            )
          )
   ]
);

我已经尽力使关卡无法正常工作。我得到的只是空白页。请帮我解决一下这个。谢谢:)

解决方案:

由于我已经找到了出路,所以我认为以后会看到此问题的朋友也将从该问题中受益。

如果您想一窥,这就是答案的链接:Solution to my problem

在使用tabbarcode的类中,将TabWidget包裹在Expanded()内,其余部分将保持不变,并且工作已完成。

body: Column(
   mainAxisSize: MainAxisSize.min,
   crossAxisAlignment: CrossAxisAlignment.stretch,
   children: <Widget>[
     Text('Heading'),
     Container(),
     Expanded(
      child: TabWidget(//your content goes here)
     )

特别感谢MFARKAN

请注意,永远不要在ListView()或任何可滚动的小部件内使用Expanded()或Flexible(),因为它们需要有限的高度。在内容中使用它,但不用于Expanded()

谢谢你们! :)

1 个答案:

答案 0 :(得分:0)

重申解决方案以关闭线程。如在GitHub上发布的issue ticket中所述,import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Expanded( child: TabWidget(), ), ); } } class TabWidget extends StatefulWidget { @override _TabWidgetState createState() => _TabWidgetState(); } class _TabWidgetState extends State<TabWidget> with SingleTickerProviderStateMixin { TabController _controller; @override void initState() { super.initState(); _controller = TabController(length: 3, vsync: this); } @override Widget build(BuildContext context) { return Container( margin: EdgeInsets.symmetric(horizontal: 10.0), child: Column( children: <Widget>[ TabBar( labelColor: Colors.black, indicatorColor: Colors.blue, controller: _controller, tabs: <Widget>[ Tab( text: 'Tab 1', ), Tab( text: 'Tab 2', ), Tab( text: 'Tab 3', ), ], ), Expanded( child: TabBarView( controller: _controller, children: <Widget>[ Center( child: Text('Tab View 1'), ), Center( child: Text('Tab View 2'), ), Center( child: Text('Tab View 3'), ), ], ), ) ], ), ); } } 要求渲染有限的高度。这可以通过使用已发布的错误日志和此GitHub thread

中发布的解决方案中所建议的扩展小部件来实现。

这里是一个最小的复制品,您可以尝试

CASE motorState OF
    MOTOR_DISABLED:
    //do something here

    MOTOR_READY:
    //do something here

    MOTOR_RUNNING:
    //do something here
END_CASE

应用外观

enter image description here