3

I have been using TabBar() in my flutter app, and it was working unless I found it my TabBarView() messes up when the screen size changes. After following this question I have found out the solution to my problem is Expanded() for TabBarView(). I have tried my level best but all I'm getting is a lot of error regarding rendering my data.

       ⡿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.

Now to give you an insight of what I have been doing is that, I have a widget class in which I have defined my TabBar and I'm using this in different places.

This is my widget for TabBar class:

@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
            ],
          )
        )
      ]
    );

The data with widget. is coming from it's constructor.

Now I have been using this in my page which has ListView() for my TabBarView() children, so I'm passing it from them only.

Class Using TabBar Code:

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()
            )
          )
   ]
);

I have tried my level best couldn't get it to work. All I'm getting is a blank page nothing else. Please help me with this. Thanks :)

SOLUTION:

Since I have found a way out, so I think my friends who will see this question in the future will get benefited from the question as well.

This is the link to the answer by the way if you want to take a peek of that : Solution to my problem

In the class using tabbarcode, wrap the TabWidget inside Expanded() and rest will be the same, and your job is done.

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

Special thanks to MFARKAN.

Please note, never ever uses Expanded() or Flexible() inside the ListView() or any scrollable widget, cos they require a finite height. use it inside the content but not for Expanded()

Thanks Guys! :)

Alok
  • 8,452
  • 13
  • 55
  • 93
  • try removing `mainAxisSize` in `Column` and most importantly `shrinkwrap: true` is causing the error, remove both of them and let me know. – Blasanka May 22 '19 at 10:08
  • not working out for me @Blasanka. `RenderFlex children have non-zero flex but incoming height constraints are unbounded.` and many more errors like this – Alok May 22 '19 at 10:43
  • i have opened issue for this , i think you check this issue on github/flutter ; https://github.com/flutter/flutter/issues/33072 – MFARKAN May 22 '19 at 10:57
  • Okay, I will check @MFARKAN – Alok May 22 '19 at 11:00
  • @MFARKAN, thanks to you and I have mentioned you in my edits as well in the question. :) – Alok May 22 '19 at 19:12
  • 1
    you're welcome dude i didnt anything and thank you to mention <3 – MFARKAN May 22 '19 at 19:27
  • answered @ https://github.com/flutter/flutter/issues/33072#issuecomment-494882905 – TWL Feb 07 '20 at 18:00

1 Answers1

3

Reiterating the solution to close the thread. As mentioned in this issue ticket posted on GitHub, TabBarView requires a finite height to be rendered. This can be achieved by using Expanded widget as suggested in the error logs posted and on the solution posted in this GitHub thread

Here's a minimal repro that you can try out

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'),
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
}

How the app looks

enter image description here

Omatt
  • 8,564
  • 2
  • 42
  • 144