1

I have a StatefullWidget containing a Scaffold, a Scrollview in its body, a BottomAppBar with a notch containing a FloatingActionButton.

When scrolling around randomly, the following assertion error is thrown:

I/flutter (29780): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (29780): The following assertion was thrown during performLayout():
I/flutter (29780): 'package:flutter/src/material/scaffold.dart': Failed assertion: line 423 pos 16: 'bodyMaxHeight <=
I/flutter (29780): math.max(0.0, looseConstraints.maxHeight - contentTop)': is not true.
I/flutter (29780): 
I/flutter (29780): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (29780): more information in this error message to help you determine and fix the underlying cause.
I/flutter (29780): In either case, please report this assertion by filing a bug on GitHub:
I/flutter (29780):   https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter (29780): 
I/flutter (29780): When the exception was thrown, this was the stack:
I/flutter (29780): #2      _ScaffoldLayout.performLayout (package:flutter/src/material/scaffold.dart:423:16)
I/flutter (29780): #3      MultiChildLayoutDelegate._callPerformLayout (package:flutter/src/rendering/custom_layout.dart:212:7)
I/flutter (29780): #4      RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:356:14)
I/flutter (29780): #5      RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1519:7)
I/flutter (29780): #6      PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:766:18)
I/flutter (29780): #7      _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:347:19)
I/flutter (29780): #8      _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:701:13)
I/flutter (29780): #9      _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:286:5)
I/flutter (29780): #10     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1012:15)
I/flutter (29780): #11     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:952:9)
I/flutter (29780): #12     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:864:5)
I/flutter (29780): #16     _invoke (dart:ui/hooks.dart:219:10)
I/flutter (29780): #17     _drawFrame (dart:ui/hooks.dart:178:3)
I/flutter (29780): (elided 5 frames from class _AssertionError and package dart:async)
I/flutter (29780): 
I/flutter (29780): The following RenderObject was being processed when the exception was fired:
I/flutter (29780):   RenderCustomMultiChildLayoutBox#0211b NEEDS-LAYOUT NEEDS-PAINT
I/flutter (29780):   creator: CustomMultiChildLayout ← AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ←
I/flutter (29780):   _InkFeatures-[GlobalKey#fe169 ink renderer] ← NotificationListener<LayoutChangedNotification> ←
I/flutter (29780):   PhysicalModel ← AnimatedPhysicalModel ← Material ← PrimaryScrollController ← _ScaffoldScope ←
I/flutter (29780):   Scaffold ← ⋯
I/flutter (29780):   parentData: <none> (can use size)
I/flutter (29780):   constraints: BoxConstraints(w=411.4, h=683.4)
I/flutter (29780):   size: Size(411.4, 683.4)
I/flutter (29780): This RenderObject had the following descendants (showing up to depth 5):
I/flutter (29780):   _RenderLayoutBuilder#c4759 relayoutBoundary=up1
I/flutter (29780):     RenderConstrainedBox#f3db9 relayoutBoundary=up2
I/flutter (29780):       RenderRepaintBoundary#7768d NEEDS-PAINT
I/flutter (29780):         RenderCustomPaint#4fd8f NEEDS-PAINT
I/flutter (29780):           RenderRepaintBoundary#3b2ce
I/flutter (29780):   RenderConstrainedBox#f158f relayoutBoundary=up1 NEEDS-PAINT
I/flutter (29780):     RenderPhysicalShape#9331d NEEDS-PAINT
I/flutter (29780):       RenderCustomPaint#26663 NEEDS-PAINT
I/flutter (29780):         _RenderInkFeatures#a489b NEEDS-PAINT
I/flutter (29780):           RenderPadding#db65e NEEDS-PAINT
I/flutter (29780):   RenderStack#80cab relayoutBoundary=up1
I/flutter (29780):     RenderTransform#033b9 relayoutBoundary=up2
I/flutter (29780):       RenderTransform#b621a relayoutBoundary=up3
I/flutter (29780):         RenderSemanticsAnnotations#56fe9 relayoutBoundary=up4
I/flutter (29780):           _RenderInputPadding#e9ac7 relayoutBoundary=up5
I/flutter (29780): ════════════════════════════════════════════════════════════════════════════════════════════════════

Because we are using a BottomAppBar with a notch and a FloatingActionButton (FAB) inside it, we want the area behind the FAB, forming the notch, to be transparent, because we are hiding the BottomAppBar on scroll, with the help of an AnimatedContainer. Therefore we have set the following flag set to true inside our Scaffold:

extendBody: true

When removing this flag, the error does not occur anymore, but as stated above, this is not an option for us.

We created a sample code to replicate the error, in as small a scale as possible:

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  MyHomePageState createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  ScrollController _scrollController;
  bool _visible = true;

  @override
  void initState() {
    super.initState();

    _scrollController = ScrollController();
    _scrollController.addListener(() {
      if (_scrollController.position.userScrollDirection ==
          ScrollDirection.reverse) {
        setState(() {
          _visible = false;
        });
      }

      if (_scrollController.position.userScrollDirection ==
          ScrollDirection.forward) {
        setState(() {
          _visible = true;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    double _bottomAppBarHeight = MediaQuery.of(context).size.width * 0.1;

    return Scaffold(
      extendBody: true,
      body: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        child: SingleChildScrollView(
          controller: _scrollController,
          child: Column(
            children: <Widget>[
              Text('Top'),
              Container(
                color: Colors.red,
                height: MediaQuery.of(context).size.height,
              ),
              Text('Bottom'),
            ],
          ),
        ),
      ),
      bottomNavigationBar: AnimatedContainer(
        duration: Duration(milliseconds: 300),
        curve: Curves.linear,
        height: _visible ? _bottomAppBarHeight : 0.0,
        child: BottomAppBar(
          color: Colors.green,
          shape: CircularNotchedRectangle(),
          child: IconButton(
            onPressed: () {},
            icon: Icon(Icons.menu),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    );
  }
}

Our current flutter version is:

Flutter (Channel stable, v1.5.4-hotfix.2, on Microsoft Windows [Version 10.0.17134.799], locale de-DE)

Is this actually a problem of flutter itself, or are we just missing something important?

Update

We have created an issue in the flutter repo on GitHub: https://github.com/flutter/flutter/issues/34326

0 Answers0