I want to design a custom navigation window like the one below.
What I planned to do is:
I did the first 3 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,), ), ); } }
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:
Let me know if I'm wrong about this, but it sounds like you want the navigation drawer to open when the user clicks the menu button. Thankfully, flutter already handles this!
You can simply use the Scaffold's drawer
property. You pass it a drawer (or possibly another widget) to show, and it will automatically handle making it available for swiping in from the left.
If you also want to open it on a button press you can use Scaffold.of(context).openDrawer();
from your button. Note that to get the context that includes the scaffold, you'll have to use a Builder or make your appbar a new widget.