I want to design a custom navigation window like the one below.
I planned to:
- Create my navigation widget
- Create my news feed widget
- Stack both widgets (news feed on top of the navigation)
- If the menu icon is clicked, translate the news feed widget to some value so that the underneath nav widget is visible
I did the first three steps. I have problems with the fourth one. I set an Offset state variable and placed my scaffold widget within a Positioned widget. I set the 'left' of the Positioned class to Offset.dx.
Code:
import 'package:flutter/material.dart'; import 'package:flutter/animation.dart'; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Flutter Demo', theme: new ThemeData( primarySwatch: const MaterialColor(0xfff06000, const { 50: const Color(0xfffff0e6), 100: const Color(0xffffd1b3), 200: const Color(0xffffb380), 300: const Color(0xffff944d), 400: const Color(0xffff751a), 500: const Color(0xfff06000), 600: const Color(0xffcc5200), 700: const Color(0xffb34700), 800: const Color(0xff993d00), 900: const Color(0xff662900), })), //I stack the classes home: new Stack( children: [ new MyNavPage(), new MyHomePage(title: "Home",initialOffset: new Offset(0.0, 0.0),), ], ) ); } } // This is my news feed class class MyHomePage extends StatefulWidget { final String title; final Offset initialOffset; MyHomePage({Key key, this.title, this.initialOffset}) : super(key: key); @override _MyHomePageState createState() => new _MyHomePageState(); } class _MyHomePageState extends State with TickerProviderStateMixin { Offset position = new Offset(0.0, 0.0); int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } void initState() { super.initState(); position = widget.initialOffset; } @override Widget build(BuildContext context) { final scaffold = new Scaffold( primary: true, appBar: new AppBar( title: new Text(widget.title), centerTitle: true, leading: new IconButton(icon: new Icon(Icons.menu),onPressed: () => setState(() => position = new Offset(100.0, 0.0)),), ), backgroundColor: Colors.white30, body: new Container( child: new Center( child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: [ new Text( 'You have pushed the button this many times:', ), new Text( '$_counter', style: Theme .of(context) .textTheme .display1, ), ], ), ), ), floatingActionButton: new FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: new Icon(Icons.add), ), ); return new Positioned( left: position.dx, child:scaffold, ); } } // My navigation class. It has those navigation options as a column to the left. // The width is 100.0, hence I offset my home page by 100.0 class MyNavPage extends StatefulWidget { MyNavPage({Key key}) : super(key: key); @override _MyNavPageState createState() => new _MyNavPageState(); } class _MyNavPageState extends State { @override Widget build(BuildContext context) { Expanded createNavChild(Icon i, Text t) { return new Expanded( child: new GestureDetector( child: new Container( width: 100.0, decoration: new BoxDecoration(color: Colors.red,), child: new Column( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ i, t ], ), ), ), ); } return new Scaffold( primary: true, body: new Container( margin: MediaQuery .of(context) .padding, child: new Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ createNavChild(new Icon(Icons.home, size: 30.0), new Text("Home")), createNavChild( new Icon(Icons.person_add, size: 30.0), new Text("Register")), createNavChild( new Icon(Icons.search, size: 30.0), new Text("Player Search")), createNavChild( new Icon(Icons.event, size: 30.0), new Text("Events")), createNavChild(new Icon(Icons.file_download, size: 30.0), new Text("Downloads")), createNavChild( new Icon(Icons.call, size: 30.0), new Text("Contact")), ], ), decoration: new BoxDecoration(color: Colors.transparent,), ), ); } }
An error is thrown:
I/flutter ( 3090): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════ I/flutter ( 3090): The following assertion was thrown during performLayout(): I/flutter ( 3090): RenderCustomMultiChildLayoutBox object was given an infinite size during layout. I/flutter ( 3090): This probably means that it is a render object that tries to be as big as possible, but it was put I/flutter ( 3090): inside another render object that allows its children to pick their own size. I/flutter ( 3090): The nearest ancestor providing an unbounded width constraint is: I/flutter ( 3090): RenderStack#df1fd NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): creator: Stack ← Semantics ← Builder ← RepaintBoundary-[GlobalKey#274fe] ← IgnorePointer ← I/flutter ( 3090): FadeTransition ← FractionalTranslation ← SlideTransition ← _MountainViewPageTransition ← I/flutter ( 3090): AnimatedBuilder ← RepaintBoundary ← _FocusScopeMarker ← ⋯ I/flutter ( 3090): parentData: (can use size) I/flutter ( 3090): constraints: BoxConstraints(w=360.0, h=640.0) I/flutter ( 3090): size: Size(360.0, 640.0) I/flutter ( 3090): alignment: AlignmentDirectional.topStart I/flutter ( 3090): textDirection: ltr I/flutter ( 3090): fit: loose I/flutter ( 3090): overflow: clip I/flutter ( 3090): The nearest ancestor providing an unbounded height constraint is: I/flutter ( 3090): RenderStack#df1fd NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): creator: Stack ← Semantics ← Builder ← RepaintBoundary-[GlobalKey#274fe] ← IgnorePointer ← I/flutter ( 3090): FadeTransition ← FractionalTranslation ← SlideTransition ← _MountainViewPageTransition ← I/flutter ( 3090): AnimatedBuilder ← RepaintBoundary ← _FocusScopeMarker ← ⋯ I/flutter ( 3090): parentData: (can use size) I/flutter ( 3090): constraints: BoxConstraints(w=360.0, h=640.0) I/flutter ( 3090): size: Size(360.0, 640.0) I/flutter ( 3090): alignment: AlignmentDirectional.topStart I/flutter ( 3090): textDirection: ltr I/flutter ( 3090): fit: loose I/flutter ( 3090): overflow: clip I/flutter ( 3090): The constraints that applied to the RenderCustomMultiChildLayoutBox were: I/flutter ( 3090): BoxConstraints(unconstrained) I/flutter ( 3090): The exact size it was given was: I/flutter ( 3090): Size(Infinity, Infinity) I/flutter ( 3090): See https://flutter.io/layout/ for more information. I/flutter ( 3090): When the exception was thrown, this was the stack: I/flutter ( 3090): #0 RenderBox.debugAssertDoesMeetConstraints. (package:flutter/src/rendering/box.dart:1698:9) I/flutter ( 3090): #1 RenderBox.debugAssertDoesMeetConstraints (package:flutter/src/rendering/box.dart:1772:6) I/flutter ( 3090): #2 RenderBox.size=. (package:flutter/src/rendering/box.dart:1507:17) I/flutter ( 3090): #3 RenderBox.size= (package:flutter/src/rendering/box.dart:1507:65) I/flutter ( 3090): #4 RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:354:5) I/flutter ( 3090): #5 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #6 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #7 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #8 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #9 _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1141:11) I/flutter ( 3090): #10 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #11 RenderStack.performLayout (package:flutter/src/rendering/stack.dart:553:15) I/flutter ( 3090): #12 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #13 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #14 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #15 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #16 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #17 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #18 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #19 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #20 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #21 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #22 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #23 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #24 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #25 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #26 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #27 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #28 RenderOffstage.performLayout (package:flutter/src/rendering/proxy_box.dart:2712:13) I/flutter ( 3090): #29 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #30 RenderStack.performLayout (package:flutter/src/rendering/stack.dart:514:15) I/flutter ( 3090): #31 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #32 __RenderTheatre&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #33 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #34 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #35 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #36 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #37 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #38 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #39 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #40 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #41 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #42 RenderView.performLayout (package:flutter/src/rendering/view.dart:125:13) I/flutter ( 3090): #43 RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1445:7) I/flutter ( 3090): #44 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:709:18) I/flutter ( 3090): #45 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:270:19) I/flutter ( 3090): #46 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:627:13) I/flutter ( 3090): #47 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:208:5) I/flutter ( 3090): #48 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15) I/flutter ( 3090): #49 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9) I/flutter ( 3090): #50 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.scheduleWarmUpFrame. (package:flutter/src/scheduler/binding.dart:751:7) I/flutter ( 3090): #52 _Timer._runTimers (dart:isolate/runtime/libtimer_impl.dart:382:19) I/flutter ( 3090): #53 _Timer._handleMessage (dart:isolate/runtime/libtimer_impl.dart:416:5) I/flutter ( 3090): #54 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:165:12) I/flutter ( 3090): (elided one frame from package dart:async) I/flutter ( 3090): The following RenderObject was being processed when the exception was fired: I/flutter ( 3090): RenderCustomMultiChildLayoutBox#04aef relayoutBoundary=up3 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): creator: CustomMultiChildLayout ← AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ← I/flutter ( 3090): _InkFeatures-[GlobalKey#64807 ink renderer] ← NotificationListener ← I/flutter ( 3090): PhysicalModel ← AnimatedPhysicalModel ← Material ← PrimaryScrollController ← _ScaffoldScope ← I/flutter ( 3090): Scaffold ← ⋯ I/flutter ( 3090): parentData: (can use size) I/flutter ( 3090): constraints: BoxConstraints(unconstrained) I/flutter ( 3090): size: Size(Infinity, Infinity) I/flutter ( 3090): This RenderObject had the following descendants (showing up to depth 5): I/flutter ( 3090): RenderPositionedBox#4ac32 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderFlex#a08f4 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderParagraph#eba89 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderParagraph#5afd6 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderConstrainedBox#0b71f NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderPhysicalModel#fa853 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): _RenderInkFeatures#45d75 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderPositionedBox#7bd87 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderPadding#3faff NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderStack#4eccb NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderTransform#16934 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderTransform#317f7 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderSemanticsAnnotations#f02cf NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderConstrainedBox#75c14 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): ════════════════════════════════════════════════════════════════════════════════════════════════════
Questions:
- Is my approach correct?
- If it is correct, what is the error telling me?
- If it is not the right approach, is there a simpler or better way to achieve this?
new MyNavPage()
at the start of thebuild
method? Have you tried using/extending a standard app drawer withScaffold
and changing the width? – Jacob Phillips